【问题标题】:Merge pandas dataframes based on value in row根据行中的值合并熊猫数据框
【发布时间】:2018-09-05 20:28:15
【问题描述】:

我有两个数据框 df1 和 df2,并希望根据其中一列中的值将它们合并到 df3,如下所示。

请问,我该怎么做?

df1:

+---+----+
|   | b  |
+---+----+
| 1 |  3 |
| 2 |  4 |
| 3 |  7 |
| 4 |  8 |
| 5 | 10 |
+---+----+

df2:

+---+-------+-----+
|   |   x   |  y  |
+---+-------+-----+
| 3 | True  | 5.4 |
| 3 | False | 6.9 |
| 4 | True  | 9.8 |
| 7 | True  | 7.8 |
| 8 | False | 5.6 |
+---+-------+-----+

df3:

+---+---+--------+-----+
|   | b | y_notx | y_x |
+---+---+--------+-----+
| 1 | 3 | 6.9    | 5.4 |
| 2 | 4 | NaN    | 9.8 |
| 3 | 7 | NaN    | 7.8 |
| 4 | 8 | 5.6    | NaN |
+---+---+--------+-----+

代码:

import pandas as pd

t1 = {'b': [3, 4, 7, 8, 10]}

df1 = pd.DataFrame(t1, index=[1,2,3,4,5])


t2 = {'x' : [True, False, True, True, False],
     'y' : [5.4,6.9,9.8,7.8,5.6]}

df2 = pd.DataFrame(t2, index=[3,3,4,7,8])

t3 = {'b': [3, 4, 7, 8],
      'y_x': [5.4, 9.8, 7.8, pd.np.nan],
      'y_notx': [6.9, pd.np.nan, pd.np.nan, 5.6]}

df3 = pd.DataFrame(t3, index=[1, 2, 3, 4])

【问题讨论】:

  • 您能否详细解释一下用于获取df3 的操作?术语b 确定在df2 下查找哪个索引,并返回y_x 下的x True 术语和y_notx 下的x False 术语。而b 列由df1 确定?对吗?
  • 是的,没错! :-)
  • 非常有趣的问题,感谢发帖。

标签: python pandas dataframe


【解决方案1】:

我认为需要:

df4 = (df2.reset_index().pivot('index','x','y')
         .rename_axis('b')
         .reset_index()
         .merge(df1, on='b')
         .rename(columns={True:'y_x', False:'y_notx'}))
print (df4)
   b  y_notx  y_x
0  3     6.9  5.4
1  4     NaN  9.8
2  7     NaN  7.8
3  8     5.6  NaN

解释:

  1. 第一个pivot 第二个DataFrame
  2. merge 通过内连接(默认)
  3. 重命名布尔列

编辑:

多列的解决方案:

t1 = {'b': [3, 4, 7, 8, 10], 'c':range(5)}

df1 = pd.DataFrame(t1, index=[1,2,3,4,5])


t2 = {'x' : [True, False, True, True, False],
     'y' : [5.4,6.9,9.8,7.8,5.6],
      'v':np.arange(5) + 4.8,
      'w':np.arange(5) -2.75,
      'Z':np.arange(5) * 0.75  }

df2 = pd.DataFrame(t2, index=[3,3,4,7,8])

t3 = {'b': [3, 4, 7, 8],
      'y_x': [5.4, 9.8, 7.8, pd.np.nan],
      'y_notx': [6.9, pd.np.nan, pd.np.nan, 5.6]}

df3 = pd.DataFrame(t3, index=[1, 2, 3, 4])

df4 = (df2.set_index('x', append=True)
          .unstack()
          .rename(columns={True:'_x', False:'_notx'})
          .rename_axis('b'))
df4.columns = df4.columns.map('_'.join)
df4 = df4.reset_index() .merge(df1, on='b')

print (df4)

   b  Z__notx  Z__x  v__notx  v__x  w__notx  w__x  y__notx  y__x  c
0  3     0.75  0.00      5.8   4.8    -1.75 -2.75      6.9   5.4  0
1  4      NaN  1.50      NaN   6.8      NaN -0.75      NaN   9.8  1
2  7      NaN  2.25      NaN   7.8      NaN  0.25      NaN   7.8  2
3  8     3.00   NaN      8.8   NaN     1.25   NaN      5.6   NaN  3

【讨论】:

  • 谢谢!这非常有效,我已将其标记为已接受的答案。不过,作为奖励,如果 df1 和 df2 有更多列,你能找到一个可行的解决方案吗?例如,如果 df1 在 b 旁边有一列 c,而 df2 列 v、w、z 具有任意值 - 您将如何合并它们,以保留所有信息,但使用足够的“未堆叠”方式_x 和 _notx 作为新的列名。
  • @peternator - 给我一些时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 2017-09-15
  • 2019-01-25
  • 2013-09-26
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
相关资源
最近更新 更多