2017-09-04 6 views
1

Ich bin neu im Pandas-Modul. Ich habe eine kleine Frage bezüglich Pandas Merge-Methode. Angenommen, ich habe zwei getrennte Tabellen, wie folgt:Pandas verschmelzen zwei Datenrahmen

Original_DataFrame

machine weekNum Percent 
M1  2  75 
M1  5  80 
M1  8  95 
M1  10  90 

New_DataFrame

machine weekNum Percent 
M1  1  100 
M1  2  100 
M1  3  100 
M1  4  100 
M1  5  100 
M1  6  100 
M1  7  100 
M1  8  100 
M1  9  100 
M1  10  100 

I verwendet merge Methode der pandas Modul, wie folgt:

pd.merge(orig_df, new_df, on='weekNum', how='left') 

ich wie folgt:

machine weekNum Percent_x Percent_y 
0 M1   2  75   100 
1 M1   5  80   100 
2 M1   8  95   100 
3 M1   10  90   100 

Aber ich bin auf der Suche die übersprungenen weeknums zu füllen und für die Zeilen stellen 100 die gewünschte Ausgabe zu erhalten, wie folgt.

machine weekNum Percent 
M1  1  100 
M1  2  75 
M1  3  100 
M1  4  100 
M1  5  80 
M1  6  100 
M1  7  100 
M1  8  95 
M1  9  100 
M1  10  90 

Kann mir bitte jemand sagen, wie ich vorgehen soll?

Antwort

1

Ich glaube, Sie brauchen combine_first, aber zuerst set_index durch gemeinsame Spalten:

df11 = df1.set_index(['machine','weekNum']) 
df22 = df2.set_index(['machine','weekNum']) 

df = df11.combine_first(df22).astype(int).reset_index() 
print (df) 
    machine weekNum Percent 
0  M1  1  100 
1  M1  2  75 
2  M1  3  100 
3  M1  4  100 
4  M1  5  80 
5  M1  6  100 
6  M1  7  100 
7  M1  8  95 
8  M1  9  100 
9  M1  10  90 


df.plot.bar('weekNum', 'Percent') 

graph

EDIT:

Für Etiketten:

plt.figure(figsize=(12, 8)) 
ax = df.plot.bar('weekNum', 'Percent') 
rects = ax.patches 

for rect, label in zip(rects, df['Percent']): 
    height = rect.get_height() 
    ax.text(rect.get_x() + rect.get_width()/2, height + 1, label, ha='center', va='bottom') 

plt.ylim(ymax=120) 

graph2

+0

gibt mir einen Fehler wie folgt, nach dem zweitletzten Code ausgeführt wird: Valueerror: invalid wörtliche für int() mit Basis 10: – SalN85

+0

Leider 'M1', ich Tippfehler in der ersten Version von Code. Brauchen Sie 'df11' und' df22' - 'df = df11.combine_first (df22) .astype (int) .reset_index()' – jezrael

+0

Immer noch der gleiche Fehler. ValueError: ungültiges Literal für int() mit Basis 10: 'M1' :( – SalN85

0

nicht so elegant wie die andere Lösung, funktioniert aber trotzdem:

# join 
merged = pd.merge(data1, data2, on=['machine','weekNum'], how='outer') 
# combine percent columns 
merged['Percent'] = merged['Percent_x'].fillna(merged['Percent_y']) 
# remove extra columns 
result = merged[['machine','weekNum', 'Percent']] 

Ergebnis:

machine weekNum Percent 
M1 2 75 
M1 5 80 
M1 8 95 
M1 10 90 
M1 1 100 
M1 3 100 
M1 4 100 
M1 6 100 
M1 7 100 
M1 9 100 
+0

Das stimmt, aber ich möchte die Datensätze von weekNumbers 2,5,8 und 10 mit den ursprünglichen Daten überschreiben. – SalN85

+0

Funktioniert! danke derline – SalN85

0

Sie könnten dies versuchen. Abhängig von Ihrem Gesamtziel ist dies möglicherweise nicht "programmatisch" genug.

import pandas as pd  
df1 = pd.DataFrame({"machine":["M1"]*4, "WeekNum": [2,5,8,10], "Percent":[75,80,95,90]}) 
df2 = pd.DataFrame({"machine":["M1"]*10,"WeekNum":np.arange(1,11,1),"Percent":[100]*10}) 
newcol = df2.merge(df1, on = "WeekNum", how = "outer")["Percent_y"].fillna(100) 
df2["Percent"] = newcol 
Verwandte Themen