簡體   English   中英

合並和更新具有重疊列的多個 pandas 數據幀

[英]Merging and updating multiple pandas dataframes with overlapping columns

我現在很難合並和更新 Pandas 數據幀。

我有一堆 CSV 文件,我正在用 pandas 解析(這不是問題)。 在極少數情況下,我有多個文件,其中包含兩個文件中都存在的一些列。

因此,例如,假設我有:

import pandas as pd

a = pd.DataFrame({"A": [0, 1, 2, 3], "B": [4, 5, 6, 7]}, index=[0,1,2,3])
b = pd.DataFrame({"A": [11, 12, 13, 14]}, index=[41,51,61,71])
c = pd.DataFrame({"A": [110, 111, 113]}, index=[0,1,3])

我想要的是這個 dataframe:

     A  B
0  110  4
1  111  5
2    2  6
3  113  7
41  11  NaN
51  12  NaN
61  13  NaN
71  14  NaN

Pandas 有這個很好的指南: Merge, join, concatenate and compare 但是我找不到解決我想要實現的目標的方法。

例如a.join(b, how="outer")引發ValueError: columns overlap but no suffix specified: Index(['A'], dtype='object') 傳遞rsuffix="R"不是一個選項,因為最終結果是:

      A    B    AR
0   0.0  4.0   NaN
1   1.0  5.0   NaN
2   2.0  6.0   NaN
3   3.0  7.0   NaN
41  NaN  NaN  11.0
51  NaN  NaN  12.0
61  NaN  NaN  13.0
71  NaN  NaN  14.0

不完全是我想要的。

pd.merge(a, b, how="outer")看起來很有前途,但也不太正確,因為索引被忽略了:

    A    B
0   0  4.0
1   1  5.0
2   2  6.0
3   3  7.0
4  11  NaN
5  12  NaN
6  13  NaN
7  14  NaN

傳遞left_index=Trueright_index=True會產生類似於.join(..., rsuffix="_x", lsuffix="_y") ,所以不是我想要的。

使用update幾乎是我想要的, a.merge(c)a修改為

       A  B
0  110.0  4
1  111.0  5
2    2.0  6
3  113.0  7

但是a.update(b)什么都不做(我假設是因為ab的索引是分離的)。

那么,我想要的甚至可以用一行代碼實現嗎?

編輯

我想出了這個:

> lll = pd.concat([a,b, c]).sort_index()
> pd.concat([a,b,c]).sort_index().drop_duplicates().groupby(a.index).last()

      A    B
0   110  4.0
1   111  5.0
2     2  6.0
3   113  7.0
41   11  NaN
51   12  NaN
61   13  NaN
71   14  NaN

這就是我想要的,問題是:這是正確的還是巧合,它產生的結果與我想要的相同?


您如何確定哪個“A”列具有優先權?

按照我閱讀文件的順序。 這些文件由設備(對我來說是一種“黑匣子”)生成,並生成其中包含日期的文件。 所以我這樣做:


tasks = [parse_csv_file(fn) for fn in sorted(glob.glob("*.csv"))]
results = await asyncio.gather(*tasks)

我想這樣做(沒有錯誤檢查,因為這是一個例子):

results = iter(results)
merged_df = next(results)

for df in results:
    merged_df = the_magic_function_Im_looking_for(df)

嘗試在 axis=1 上使用concat + groupby last合並數據幀,然后獲取每個列組的“最后”有效值:

df = pd.concat([a, b, c], axis=1).groupby(level=0, axis=1).last()

df

        A    B
0   110.0  4.0
1   111.0  5.0
2     2.0  6.0
3   113.0  7.0
41   11.0  NaN
51   12.0  NaN
61   13.0  NaN
71   14.0  NaN

concat ing long 並獲得每行索引的最后有效行,這要歸功於@anky

df = pd.concat([a, b, c]).groupby(level=0).last()

df

      A    B
0   110  4.0
1   111  5.0
2     2  6.0
3   113  7.0
41   11  NaN
51   12  NaN
61   13  NaN
71   14  NaN

使用combine_first reduce ing:

from functools import reduce

to_merge = [c, b, a]

result = reduce(pd.DataFrame.combine_first, to_merge)

它連續將combine_first應用於列表的條目以結束所有組合,即最后減少 dataframe。

(如果to_merge帶有相反的順序,我們可以將reversed(to_merge)放在reduce中),

要得到

>>> result

        A    B
0   110.0  4.0
1   111.0  5.0
2     2.0  6.0
3   113.0  7.0
41   11.0  NaN
51   12.0  NaN
61   13.0  NaN
71   14.0  NaN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM