2016-05-21 3 views
4

Ich habe zwei Datenrahmen DF und DF2 und eine Liste List1. Um es einfach zu halten, verwende ich eine Beispieleingabe. DF und DF2 enthalten Elemente, die in List1 sind. DF hat eine zufällige Anordnung dieser Elemente mit einigen NaN Werten und in DF2 sind diese Elemente mit einer Nummer verknüpft. Dies ist, was ich zu tun beabsichtigen:
1. Iterate über List1 und wählen Sie die Zeilen in DF, die dieses spezielle Element haben aus List1
2. In jeder der Reihen (ich bereits dieses getan haben), führen eine Multiplikation der Werte, die den Strings in den Zeilen zugeordnet sind (die in DF2 sind)
Wie führe ich Operationen in Zeilen von Datenrahmen durch, die Elemente enthalten, die mit einem Wert in einem anderen Datenrahmen in Python verknüpft sind?

Teil 2 hat mich seit einiger Zeit verwirrt. Ich habe an verschiedene Dinge gedacht, aber ich kann mir überhaupt keine Vorstellung von einem Algorithmus machen. Ich kann die Zeichenfolgen in DF und ihre Werte in DF2 nicht verknüpfen. Bitte helfen Sie!

List1=['Apple','Orange','Banana','Pineapple','Pear','Tomato','Potato'] 
Sample DF 
    EQ1  EQ2  EQ3 
0 Apple Orange NaN 
1 Banana Potato NaN 
2 Pear  Tomato Pineapple 
3 Apple Tomato Pear 
4 Tomato Potato Banana 

DF2 
    Name  Value 
Apple  3.21 
Orange  4.32 
Banana  5.22 
Pineapple 0.01 
Pear  4.89 
Tomato  7.55 
Potato  6.49 

für Teile dabei 2: Zum Beispiel, wenn ich die Zeilen mit dem Elemente Banana, die erste Zeile auszuwählen ist, auf die zuzugreifen Banana Potato NaN. Jetzt ist Banana mit 5.22 verknüpft und Potato ist mit 6.49 in DF2 verbunden. Ich möchte den Wert der ausgewählten Zeichenfolge (in diesem Fall Banana) vorübergehend auf 1 ändern, und dann möchte ich, dass sie multipliziert werden. (1 * 6,49 in diesem Fall). Natürlich sollte NaN nicht in diesem enthalten sein. Auch die Anzahl der Spalten von DF (die Länge der Zeilen) sind nicht immer 3 (wie gezeigt). Es ist eine Variable. Da ich eine Schleife verwende, sollte diese Produktberechnung für alle Elemente von List1 durchgeführt werden. Es wäre toll, wenn mir jemand mit Part2 helfen könnte.
Gewünschter Ausgang für Banananur.

List_output=[6.49, 48.9995] 

ERKLÄRUNG DES AUSGANGS: Die Banane ist nur in 2 Reihen vorhanden. Daher gibt es nur zwei Werte in der Liste Ausgabe. Die erste ist 6,49, da diese Zeile nur zwei nicht NaN Werte hat und einer davon der ausgewählte Wert Banana ist. Daher wird der mit Banana verknüpfte Wert in 1 vorübergehend geändert und der Rest der Werte werden so beibehalten, wie sie sind. Dies muss für alle Werte in List1 durchgeführt werden. Hoffe, ich machte es klar

+0

Können Sie die gewünschte Ausgabe des Eingangs hinzufügen? 'Serie'? – jezrael

+0

Ich habe es gerade bearbeitet, um eine teilweise gewünschte Ausgabe in der Frage – controlfreak

Antwort

1

Ich glaube, Sie zuerst dict von to_dict, dann replace gleichen Wert in der Schleife durch 1 und NaN von fillna durch 1 entfernen erstellen. Dann können Sie alle Werte durch dictd und mehrere alle Spalten ersetzen.Zuletzt können Sie lists speichern lis Zum Wörterbuch:

d= DF2.set_index('Name').to_dict() 
print (d) 
{'Value': {'Banana': 5.2199999999999998, 'Pineapple': 0.01, 
      'Apple': 3.21, 'Tomato': 7.5499999999999998, 
      'Orange': 4.3200000000000003, 
      'Pear': 4.8899999999999997, 'Potato': 6.4900000000000002}} 

lis = {}  
for eq in List1: 
    #http://stackoverflow.com/a/37230933/2901002 
    df = DF[DF.isin([eq]).any(1)].reset_index(drop=True) 
    df.replace(eq,1, inplace=True) 
    df.fillna(1, inplace=1) 
    df.replace(d['Value'], inplace=True) 
    li = df.EQ1.values * df.EQ2.values * df.EQ3.values 
    lis[eq] = li.tolist() 
    print (li.tolist()) 
[4.32, 36.9195] 
[3.21] 
[6.49, 48.9995] 
[36.9195] 
[0.0755, 24.2355] 
[0.0489, 15.6969, 33.8778] 
[5.22, 39.410999999999994] 

print (lis['Banana'])  
[6.49, 48.9995]  

Eine andere Lösung mit product, die allgemeinere ist, da funktioniert, wenn Anzahl der Spalten in DF keine Konstante ist:

dfs = {} 
for eq in List1: 
    df = DF[DF.isin([eq]).any(1)].reset_index(drop=True) 
    df.replace(eq,1, inplace=True) 
    df.fillna(1, inplace=1) 
    df.replace(d['Value'], inplace=True) 
    li = df.product(axis=1) 
    dfs[eq] = li.tolist() 
    print (li.tolist()) 

[4.3200000000000003, 36.919499999999999] 
[3.21] 
[6.4900000000000002, 48.999499999999998] 
[36.919499999999999] 
[0.075499999999999998, 24.235499999999998] 
[0.048899999999999999, 15.696899999999999, 33.877800000000001] 
[5.2199999999999998, 39.410999999999994]  

print (dfs['Banana'])  
[6.4900000000000002, 48.999499999999998] 

print (DF) 
     EQ1  EQ2  EQ3 
0 Apple Orange  NaN 
1 Banana Potato  NaN 
2 Pear Tomato Pineapple 
3 Apple Tomato  Pear 
4 Tomato Potato  Banana 
+0

Nun, die Anzahl der Spalten in 'DF' ist keine Konstante und es kann 3 oder 4 oder etwas anderes sein. Wird das für einen allgemeinen Fall funktionieren? – controlfreak

+0

Das Produkt ist allgemeiner, oder? – controlfreak

+0

Ja, genau. Die zweite Lösung ist allgemeiner, da "Produkt" mehrere Spalten enthält. – jezrael

2

Ein Weg wäre, merge DF und DF2 dreimal so.

In [69]: DF 
Out[69]: 
     EQ1  EQ2  EQ3 
0 Apple Orange  NaN 
1 Banana Potato  NaN 
2 Pear Tomato Pineapple 
3 Apple Tomato  Pear 
4 Tomato Potato  Banana 

In [70]: new_cols = ['V' + c for c in DF] 

In [72]: for c, new_c in zip(DF, new_cols): 
    ...:  DF = DF.merge(DF2.rename(columns={'Value': new_c}), 
    ...:     how='left', left_on=c, right_on='Name') 
    ...:  

In [73]: DF[new_cols] 
Out[73]: 
    VEQ1 VEQ2 VEQ3 
0 3.21 4.32 NaN 
1 5.22 6.49 NaN 
2 4.89 7.55 0.01 
3 3.21 7.55 4.89 
4 7.55 6.49 5.22 

In [74]: DF[new_cols].fillna(1.).product(axis=1) 
Out[74]: 
0  13.867200 
1  33.877800 
2  0.369195 
3 118.511595 
4 255.777390 
dtype: float64 
+0

zu enthalten Danke für die Antwort! Es tut mir wirklich leid, dass ich die Frage falsch geschrieben habe. Jetzt habe ich es bearbeitet und es ist jetzt gut – controlfreak

0

ich denke, das ist ein Anwendungsfall für df.replace, der bequem eine Serie akzeptiert.

import pandas as pd 
from io import StringIO 

df1 = pd.read_csv(StringIO(
''' 
    EQ1  EQ2  EQ3 
0 Apple Orange NaN 
1 Banana Potato NaN 
2 Pear  Tomato Pineapple 
3 Apple Tomato Pear 
4 Tomato Potato Banana 
'''), sep=r' +') 

df2 = pd.read_csv(StringIO(
''' 
    Name  Value 
Apple  3.21 
Orange  4.32 
Banana  5.22 
Pineapple 0.01 
Pear  4.89 
Tomato  7.55 
Potato  6.49 
'''), sep=r' +') 


# convert df to series 
s2 = df2.set_index('Name').Value 

df3 = df1.replace(s2).product(axis=1) 

# In [19]: q.df3 
# Out[19]: 
# 0  13.867200 
# 1  33.877800 
# 2  0.369195 
# 3 118.511595 
# 4 255.777390 
# dtype: float64 
Verwandte Themen