簡體   English   中英

使用 pandas 合並時如何保留索引

[英]How to keep index when using pandas merge

我想合並兩個DataFrames ,並將第一幀的索引保留為合並數據集的索引。 但是,當我進行合並時,生成的 DataFrame 具有整數索引。 如何指定要保留左側數據框中的索引?

In [4]: a = pd.DataFrame({'col1': {'a': 1, 'b': 2, 'c': 3}, 
                          'to_merge_on': {'a': 1, 'b': 3, 'c': 4}})

In [5]: b = pd.DataFrame({'col2': {0: 1, 1: 2, 2: 3}, 
                          'to_merge_on': {0: 1, 1: 3, 2: 5}})

In [6]: a
Out[6]:
   col1  to_merge_on
a     1            1
b     2            3
c     3            4

In [7]: b
Out[7]:
   col2  to_merge_on
0     1            1
1     2            3
2     3            5

In [8]: a.merge(b, how='left')
Out[8]:
   col1  to_merge_on  col2
0     1            1   1.0
1     2            3   2.0
2     3            4   NaN

In [9]: _.index
Out[9]: Int64Index([0, 1, 2], dtype='int64')

編輯:切換到可以輕松復制的示例代碼

In [5]: a.reset_index().merge(b, how="left").set_index('index')
Out[5]:
       col1  to_merge_on  col2
index
a         1            1     1
b         2            3     2
c         3            4   NaN

請注意,對於某些左合並操作,當ab之間有多個匹配時,您最終可能會得到比a更多的行。 在這種情況下,您可能需要刪除重復項

您可以在左側數據幀上制作索引副本並進行合並。

a['copy_index'] = a.index
a.merge(b, how='left')

我發現這個簡單的方法在處理大型數據框和使用pd.merge_asof() (或dd.merge_asof() )時非常有用。

當重置索引很昂貴(大數據框)時,這種方法會更好。

有一個使用Series.mapDataFrame.set_index的非 pd.merge 解決方案。

In: a['col2'] = a['to_merge_on'].map(b.set_index('to_merge_on')['col2']))
In: a['col2']
Out:
   col1  to_merge_on  col2
a     1            1   1.0
b     2            3   2.0
c     3            4   NaN

這不會為索引引入虛擬index名稱。

但是請注意,沒有DataFrame.map方法,因此這種方法不適用於多列。

df1 = df1.merge(df2, how="inner", left_index=True, right_index=True)

這允許保留 df1 的索引

另一個簡單的選擇是將索引重命名為以前的索引:

a.merge(b, how="left").set_axis(a.index)

合並保留數據幀“a”的順序,但只是重置索引,因此使用 set_axis 是安全的

假設生成的 df 具有與您的第一個 df 相同的行數和順序,您可以這樣做:

c = pd.merge(a, b, on='to_merge_on')
c.set_index(a.index,inplace=True)

我想我想出了一個不同的解決方案。 我在索引值上加入左表,在基於左表索引的列值上加入右表。 我所做的是正常的合並:

First10ReviewsJoined = pd.merge(First10Reviews, df, left_index=True, right_on='Line Number')

然后我從合並表中檢索新的索引號,並將它們放在一個名為 Sentiment Line Number 的新列中:

First10ReviewsJoined['Sentiment Line Number']= First10ReviewsJoined.index.tolist()

然后我手動將索引設置回原始的左表索引,該索引基於預先存在的名為行號的列(我從左表索引加入的列值):

First10ReviewsJoined.set_index('Line Number', inplace=True)

然后刪除行號的索引名稱,使其保持空白:

First10ReviewsJoined.index.name = None

也許有點破解,但似乎運作良好且相對簡單。 此外,猜測它會降低重復/弄亂數據的風險。 希望這一切都說得通。

對於想要保持左索引與左連接之前一樣的人:

def left_join(
    a: pandas.DataFrame, b: pandas.DataFrame, on: list[str], b_columns: list[str] = None
) -> pandas.DataFrame:
    if b_columns:
        b_columns = set(on + b_columns)
        b = b[b_columns]
    df = (
        a.reset_index()
        .merge(
            b,
            how="left",
            on=on,
        )
        .set_index(keys=[x or "index" for x in a.index.names])
    )
    df.index.names = a.index.names
    return df

您也可以使用DataFrame.join()方法來實現相同的目的。 join方法將保留原始索引。 可以使用on參數指定要加入的列。

In [17]: a.join(b.set_index("to_merge_on"), on="to_merge_on")
Out[17]: 
   col1  to_merge_on  col2
a     1            1   1.0
b     2            3   2.0
c     3            4   NaN

暫無
暫無

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

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