【问题标题】:How to map to values inside a column of lists in pandas如何映射到熊猫列表列中的值
【发布时间】:2021-05-03 19:41:59
【问题描述】:

我有以下场景。

import pandas as pd

d = {'col1': [1, 2, 3], 'col2': [['apple'], [], ['romaine', 'potatoes']}
df = pd.DataFrame(data=d)

所以数据框是:

   col1   col2
0   1     [apple]
1   2     []
2   3     [romaine, potatoes]

我还有一本字典:

my_dict = {"apple" : "fruit", "potatoes" : "vegetable", "romaine" : "lettuce"}

我想创建另一列“col3”,其中包含来自上面 my_dict 的值列表:

   col1   col2                 col3
0   1     [apple]              [fruit]
1   2     []                   []
2   3     [romaine, potatoes]  [lettuce, vegetable]

我想用apply、map、lambda写一行代码来实现:

df["col3"] = df.col2.apply(map(lambda x: pass if not x else condition_dict[x]))

我真的很困惑,想知道是否可以不编写单独的函数然后作为参数传递给应用。

【问题讨论】:

    标签: python pandas dictionary lambda data-science


    【解决方案1】:
    • 对于具有 1M 行的示例数据帧,.applylist-comprehension.explode().groupby() 快大约 2.5 倍,并且比使用 .map() 快一点(1.15 倍)。
    • 如果列中有NaN,则该行必须用.dropna 删除,也可以用空的list 填充。
      • .fillna([]) 不起作用
      • 使用df.col2 = df.col2.fillna({i: [] for i in df.index})
    df['col3'] = df.col2.apply(lambda x: [my_dict.get(v) for v in x])
    
    # display(df)
     col1                col2                 col3
        1             [apple]              [fruit]
        2                  []                   []
        3 [romaine, potatoes] [lettuce, vegetable]
    

    %timeit测试

    # test data with 1M rows
    d = {'col1': [1, 2, 3], 'col2': [['apple'], [], ['romaine', 'potatoes']]}
    df = pd.DataFrame(d)
    df = pd.concat([df]*333333)
    
    %%timeit
    df.col2.apply(lambda x: [my_dict.get(v) for v in x])
    [out]:
    453 ms ± 30.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    def scott(d, my_dict):
        e = d.explode('col2')
        e['col3'] = e['col2'].map(my_dict)
        return e.groupby('col1', as_index=False)[['col3']].agg(list).merge(d)
    
    %%timeit
    scott(df, my_dict)
    [out]:
    1.17 s ± 23.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    %%timeit
    df.col2.map(lambda x: list(map(my_dict.get, x)))
    [out]:
    519 ms ± 16.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    %%timeit
    df['col2'].explode().map(my_dict).groupby(level=0).agg(list)
    [out]:
    909 ms ± 8.61 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

      【解决方案2】:

      试试这个:

      dfe = df.explode('col2')
      dfe['col3'] = dfe['col2'].map(my_dict)
      dfe.groupby('col1', as_index=False)[['col3']].agg(list).merge(df)
      

      输出:

         col1                  col3                 col2
      0     1               [fruit]              [apple]
      1     2                 [nan]                   []
      2     3  [lettuce, vegetable]  [romaine, potatoes]
      

      或者作为单行:

      (df.merge(df['col2'].explode()
                          .map(my_dict)
                          .groupby(df['col1'])
                          .agg(list)
                          .rename('col3'), 
                 left_on='col1', 
                 right_index=True)
      

      【讨论】:

        【解决方案3】:
        df.col2.map(lambda x: list(map(my_dict.get, x)))
        

        【讨论】:

          猜你喜欢
          • 2021-09-03
          • 1970-01-01
          • 2019-01-02
          • 2019-07-12
          • 2021-05-03
          • 2017-10-31
          • 1970-01-01
          • 1970-01-01
          • 2021-04-30
          相关资源
          最近更新 更多