我有兩個相當大的Pandas數據框,像〜300k行,一個有N〜30列(包括一個「Description」之一),另一個只有一個「Description」列。第一個df包含完整的數據,但有一些線條太多(幾千)和其他一些缺失線條(大約600),大致均勻地散佈在整個數據中;另一個正確地指定行,但沒有任何其他數據。我想將它們合併成一個單一的數據框,它具有由後者指定的行和前者的信息(即,丟棄不出現在後者中的行並在需要的地方創建新行,例如用nan's填充)。所以最終的數據幀應該有M×N的大小,M是第二個數據幀的行數。在版本合併樣式中合併使用索引的Pandas數據框
這將是一個pandas.merge的原型案例,如果不是我想要合併的鍵具有重複的事實。它們「大多是獨一無二的」,但有些條目會重複(通常在不少於100行之後),我不希望它們多次出現。相反,我想做一些看起來像「版本控制」的東西,即逐行比較以獲得兩個描述的最佳匹配,刪除第一個數據框中添加的行,並從正確的行中推出新的行。事實上,如果我只提取兩個CSV中的兩個df的「描述」列,我就可以輕鬆地用手工完成我需要的工作。融合(線條足夠長以至於在如何檢查相等的線條時確實沒有模棱兩可),但是1)這很慢並且2)它不能解決我的問題(最終我會得到第二個數據框,因爲我不得不放棄其他列使用融合)。
爲了舉例說明,說我有以下兩個dataframes:
df1 = pd.DataFrame({'Description': ['A','B','Y','D','A','E','F','Y','B'], 'Values': np.arange(9)**2})
df2 = pd.DataFrame({'Description': ['A','B','D','A','E','B','F','B']})
>>> df1
Description Values
0 A 0
1 B 1
2 Y 4
3 D 9
4 A 16
5 E 25
6 F 36
7 Y 49
8 B 64
>>> df2
Description
0 A
1 B
2 D
3 A
4 E
5 B
6 F
7 B
一個我想獲得的是:
Description Values
0 A 0.0
1 B 1.0
2 D 9.0
3 A 16.0
4 E 25.0
5 B NaN
6 F 36.0
7 B 64.0
唯一一種-的解決方案,我發現是添加一列到複製索引的第一個數據框只需
df1['id'] = df1.index
(我知道的是標準d,即np.arange(len(df1))
),使用pd.merge(df1, df2, how='right')
,然後從合併的數據幀中提取對應於列id的最大增加序列的索引。爲此,參見例如Longest increasing subsequence這將需要適應,以便始終包括序列中的任何NaN
。然而,在重新發明輪子之前,我想知道是否有人知道這個代碼的一個已經存在的實現,也許在某些用於自動化版本控制的包中?
編輯:在以前版本的問題df2
是df2 = pd.DataFrame({'Description': ['A','B','D','A','E','Z','F','B']})
。閱讀@jezrael的第一個答案,我意識到它建議額外的行是由字母Z
「特殊」,但實際上它們將出現在數據框的其他地方。這使@jezrael提出了一個非常好的和優雅的答案,但不幸的是這並不適合我。
另一方面,對於一個稍微簡化的假設,實際上要刪除的行是比較特殊的,所以我將它們重命名爲'Y',因爲我可以事先刪除它們並忽略這部分問題 - 「增加「部分是我真正關心的。
感謝快速回答!不幸的是,儘管這解決了我寫的例子,但我擔心一般情況下還有一個難題使得這個解決方案無法工作:df2中的附加行很可能已經出現在其他地方(在df1和df2中)。例如。 df2 = pd.DataFrame({'Description':['A','B','D','A','E','C','F','B']})。在這種情況下,您的解決方案會將C值賦予該行,而不是NaN(如果還有其他C向下,則會打破所有匹配,因爲cumcount()與此不同) –
:('merge' is不是有'重複'值的朋友,現在我沒有其他的想法了。你能否通過評論中的值來改變樣本? – jezrael
編輯這個問題,謝謝!我也非常感謝答案,我學會了cumcount()命令今天:-) –