【问题标题】:Search and lookup Search values from one dataframe in another dataframe and populate new column based on look up values in pandas搜索和查找 从一个数据帧到另一个数据帧中搜索值,并根据 pandas 中的查找值填充新列
【发布时间】:2020-06-17 05:23:51
【问题描述】:

我有 2 个数据框 - df1 和 df2,如下所示。我需要在 df1 的所有列(列 - a 到 f)中搜索来自 df2['Pid'] 的值,然后创建一个新列 df1['ind'],它将保存来自 df2['ind'] 的值在 df1 中找到 df2['Pid'] 的值之间的匹配。对我来说,它看起来像是一个扩展的查找案例。我使用df2.isin(df1['PERSON_UID']) 在 df1 中查找标记值 found = true/false,但停留在创建 df1['ind'] 列。

df1:

a       b       c           d       e       f
0       0       2106        0       0       0
0       2103    0           0       0       0
0       2104    0           0       0       0
0       2105    0           0       0       0
2100    0       0           0       0       0
2101    0       0           0       0       0
2102    0       0           0       0       0
0       0       2107        0       0       0
0       0       2108        0       0       0
0       0       2109        0       0       0
0       0       2110        0       0       0
0       0       2111        0       0       0
0       0       0           2112.   0       0
0       0       0           2113    0       0
0       0       0           2114    0       0
0       0       0           0       2115    0
0       0       0           0       2116    0
0       0       0           0       0       2117
0       0       0           0       0       2118
0       0       0           0       0       2119
0       0       0           0       2120    0

df2:

Pid       ind
2100        y
2101        n
2102        y
2103        n
2104        y
2105        n
2106        n
2107        n
2108        y
2109        y
2110        n
2111        y
2112        y
2113        y
2114        n
2115        n
2116        y
2117        y
2118        n
2119        y
2120        n

期望的操作:

a       b       c           d       e       f       ind
0       0       2106        0       0       0       n
0       2103    0           0       0       0       n
0       2104    0           0       0       0       y
0       2105    0           0       0       0       n
2100    0       0           0       0       0       y
2101    0       0           0       0       0       n
2102    0       0           0       0       0       y
0       0       2107        0       0       0       n
0       0       2108        0       0       0       y
0       0       2109        0       0       0       y
0       0       2110        0       0       0       n
0       0       2111        0       0       0       y
0       0       0           2112.   0       0       y
0       0       0           2113    0       0       y
0       0       0           2114    0       0       n
0       0       0           0       2115    0       n
0       0       0           0       2116    0       y
0       0       0           0       0       2117    y
0       0       0           0       0       2118    n
0       0       0           0       0       2119    y
0       0       0           0       2120    0       n

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    @jezrael 的回答很完美,如果 Pid 不是重复的,那么您需要我想将它们组合为索引的总和。

    df['Pid'] = df.sum(axis=1)
    df['Pid'] = df['Pid'].astype(int)
    df = pd.merge(df, df2, on='Pid', how='inner')
    df.drop('Pid', axis=1, inplace=True)
    
    df
        a   b   c   d   e   f   ind
    0   0   0   2106    0.0     0   0   n
    1   0   2103    0   0.0     0   0   n
    2   0   2104    0   0.0     0   0   y
    3   0   2105    0   0.0     0   0   n
    4   2100    0   0   0.0     0   0   y
    5   2101    0   0   0.0     0   0   n
    6   2102    0   0   0.0     0   0   y
    7   0   0   2107    0.0     0   0   n
    8   0   0   2108    0.0     0   0   y
    9   0   0   2109    0.0     0   0   y
    10  0   0   2110    0.0     0   0   n
    11  0   0   2111    0.0     0   0   y
    12  0   0   0   2112.0      0   0   y
    13  0   0   0   2113.0      0   0   y
    14  0   0   0   2114.0      0   0   n
    15  0   0   0   0.0     2115    0   n
    16  0   0   0   0.0     2116    0   y
    17  0   0   0   0.0     0   2117    y
    18  0   0   0   0.0     0   2118    n
    19  0   0   0   0.0     0   2119    y
    20  0   0   0   0.0     2120    0   n
    

    【讨论】:

      【解决方案2】:

      用途:

      df1['ind'] = df1.mask(df1.eq(0)).ffill(axis=1).iloc[:, -1].map(df2.set_index('Pid')['ind'])
      print (df1)
             a     b     c       d     e     f ind
      0      0     0  2106     0.0     0     0   n
      1      0  2103     0     0.0     0     0   n
      2      0  2104     0     0.0     0     0   y
      3      0  2105     0     0.0     0     0   n
      4   2100     0     0     0.0     0     0   y
      5   2101     0     0     0.0     0     0   n
      6   2102     0     0     0.0     0     0   y
      7      0     0  2107     0.0     0     0   n
      8      0     0  2108     0.0     0     0   y
      9      0     0  2109     0.0     0     0   y
      10     0     0  2110     0.0     0     0   n
      11     0     0  2111     0.0     0     0   y
      12     0     0     0  2112.0     0     0   y
      13     0     0     0  2113.0     0     0   y
      14     0     0     0  2114.0     0     0   n
      15     0     0     0     0.0  2115     0   n
      16     0     0     0     0.0  2116     0   y
      17     0     0     0     0.0     0  2117   y
      18     0     0     0     0.0     0  2118   n
      19     0     0     0     0.0     0  2119   y
      20     0     0     0     0.0  2120     0   n
      

      详情

      首先将0的值替换为DataFrame.mask的缺失值:

      print (df1.mask(df1.eq(0)))
               a       b       c       d       e       f
      0      NaN     NaN  2106.0     NaN     NaN     NaN
      1      NaN  2103.0     NaN     NaN     NaN     NaN
      2      NaN  2104.0     NaN     NaN     NaN     NaN
      3      NaN  2105.0     NaN     NaN     NaN     NaN
      4   2100.0     NaN     NaN     NaN     NaN     NaN
      5   2101.0     NaN     NaN     NaN     NaN     NaN
      6   2102.0     NaN     NaN     NaN     NaN     NaN
      7      NaN     NaN  2107.0     NaN     NaN     NaN
      8      NaN     NaN  2108.0     NaN     NaN     NaN
      9      NaN     NaN  2109.0     NaN     NaN     NaN
      10     NaN     NaN  2110.0     NaN     NaN     NaN
      11     NaN     NaN  2111.0     NaN     NaN     NaN
      12     NaN     NaN     NaN  2112.0     NaN     NaN
      13     NaN     NaN     NaN  2113.0     NaN     NaN
      14     NaN     NaN     NaN  2114.0     NaN     NaN
      15     NaN     NaN     NaN     NaN  2115.0     NaN
      16     NaN     NaN     NaN     NaN  2116.0     NaN
      17     NaN     NaN     NaN     NaN     NaN  2117.0
      18     NaN     NaN     NaN     NaN     NaN  2118.0
      19     NaN     NaN     NaN     NaN     NaN  2119.0
      20     NaN     NaN     NaN     NaN  2120.0     NaN
      

      然后正向填充缺失值:

      print (df1.mask(df1.eq(0)).ffill(axis=1))
               a       b       c       d       e       f
      0      NaN     NaN  2106.0  2106.0  2106.0  2106.0
      1      NaN  2103.0  2103.0  2103.0  2103.0  2103.0
      2      NaN  2104.0  2104.0  2104.0  2104.0  2104.0
      3      NaN  2105.0  2105.0  2105.0  2105.0  2105.0
      4   2100.0  2100.0  2100.0  2100.0  2100.0  2100.0
      5   2101.0  2101.0  2101.0  2101.0  2101.0  2101.0
      6   2102.0  2102.0  2102.0  2102.0  2102.0  2102.0
      7      NaN     NaN  2107.0  2107.0  2107.0  2107.0
      8      NaN     NaN  2108.0  2108.0  2108.0  2108.0
      9      NaN     NaN  2109.0  2109.0  2109.0  2109.0
      10     NaN     NaN  2110.0  2110.0  2110.0  2110.0
      11     NaN     NaN  2111.0  2111.0  2111.0  2111.0
      12     NaN     NaN     NaN  2112.0  2112.0  2112.0
      13     NaN     NaN     NaN  2113.0  2113.0  2113.0
      14     NaN     NaN     NaN  2114.0  2114.0  2114.0
      15     NaN     NaN     NaN     NaN  2115.0  2115.0
      16     NaN     NaN     NaN     NaN  2116.0  2116.0
      17     NaN     NaN     NaN     NaN     NaN  2117.0
      18     NaN     NaN     NaN     NaN     NaN  2118.0
      19     NaN     NaN     NaN     NaN     NaN  2119.0
      20     NaN     NaN     NaN     NaN  2120.0  2120.0
      

      使用DataFrame.iloc按位置选择最后一列:

      print (df1.mask(df1.eq(0)).ffill(axis=1).iloc[:, -1])
      0     2106.0
      1     2103.0
      2     2104.0
      3     2105.0
      4     2100.0
      5     2101.0
      6     2102.0
      7     2107.0
      8     2108.0
      9     2109.0
      10    2110.0
      11    2111.0
      12    2112.0
      13    2113.0
      14    2114.0
      15    2115.0
      16    2116.0
      17    2117.0
      18    2118.0
      19    2119.0
      20    2120.0
      Name: f, dtype: float64
      

      最后使用Series.map

      【讨论】:

      • 非常感谢!完美地工作!我刚刚执行了 pandas.merge 而不是 series.map。工作得很好。
      猜你喜欢
      • 2020-06-08
      • 2021-01-11
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 2021-01-08
      • 1970-01-01
      • 2023-03-15
      • 2021-01-26
      相关资源
      最近更新 更多