【问题标题】:Merge 2 dataframes according to length of list (using Pandas)根据列表长度合并 2 个数据帧(使用 Pandas)
【发布时间】:2017-04-23 13:11:48
【问题描述】:

我有一个数据框df1,如下所示:

import pandas as pd
import numpy as np
dic1 = {'A':['a','b','c','d','e'],
        'B':[np.nan,np.nan,np.nan,150,np.nan],
        'C':['x','y','z','v','w']}
df1 = pd.DataFrame(dic1)

然后我有第二个数据框df2

dic2 = {'X':['c','e','b'],
        'Y':[2,4,1],
        'Z':[[188],[160,200],[784]]}
df2 = pd.DataFrame(dic2)

其中“X”列对应于“A”中的一些值; “Y”列对应于“X”中存在的“A”项的值的索引。

我的目标如下:

  • 第 1 步:仅选择“Z”列中列表中具有 1 个元素的行
  • 第2步:根据“Y”中包含的索引替换“B”列中所选列表的值。

我能够通过以下代码行实现我的目标:

# Step 1
df2 = df2.loc[df2['Z'].str.len() == 1] 

# Step 2
for idx,row in df2.iterrows():
    df1.set_value(row['Y'],'B',row['Z'][0]) 

您能否建议我使用熊猫的某些功能来实现我的目标更聪明或更有效的方法?如果可能,我想避免使用 for 循环。

输出应如下所示:

# Before            # After
   A      B  C         A      B  C
0  a    NaN  x      0  a    NaN  x
1  b    NaN  y ---> 1  b  784.0  y
2  c    NaN  z ---> 2  c  188.0  z
3  d  150.0  v      3  d  150.0  v
4  e    NaN  w      4  e    NaN  w

【问题讨论】:

    标签: python pandas dataframe replace merge


    【解决方案1】:

    您可以使用DataFrame.from_recordslists 从列Z 中删除:

    df2 = df2[df2['Z'].str.len() == 1] 
    df2.Z = pd.DataFrame.from_records(df2['Z'].values.tolist(), index=df2.index)
    print (df2)
       X  Y    Z
    0  c  2  188
    2  b  1  784
    

    然后combine_firstfillnaNaN 替换为df1 的值:

    df1 = df1.set_index('A')
    df1.B = df1['B'].combine_first(df2.set_index('X')['Z'])
    #df1.B = df1['B'].fillna(df2.set_index('X')['Z'])
    print (df1.reset_index())
       A      B  C
    0  a    NaN  x
    1  b  784.0  y
    2  c  188.0  z
    3  d  150.0  v
    4  e    NaN  w
    

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 2020-04-10
      • 2022-01-07
      • 1970-01-01
      • 2019-06-17
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 2020-07-23
      相关资源
      最近更新 更多