【问题标题】:pandas dataframe iterate over cell value that is a list and compare each element to other cell熊猫数据框迭代作为列表的单元格值并将每个元素与其他单元格进行比较
【发布时间】:2021-11-23 07:26:05
【问题描述】:

我有一个包含 2 列的数据框 - 一个元组和一个列表:

df = t        l
    (1,2) [1,2,3,4,5,6]
    (0,5) [1,4,9]
    (0,4) [9,11]

我想添加一个新列“有多少来自 l 的元素在 t 的范围内。 例如,这里的 if will 是:

df =counter  t       l
      2    (1,2) [1,2,3,4,5,6]
      2    (0,5) [1,4,9]
      0    (0,4) [9,11]

最好的方法是什么?

【问题讨论】:

    标签: python-3.x pandas dataframe


    【解决方案1】:

    将列表推导与生成器和sum一起使用:

    df['counter'] = [sum(a <= i <= b for i in y) for (a, b), y in df[['t','l']].to_numpy()]
    

    set.intersection 的更快解决方案是:

    df['counter'] = [len(set(range(a, b+1)).intersection(y)) 
                     for (a, b), y in df[['t','l']].to_numpy()]
    
    print (df)
            t                   l  counter
    0  (1, 2)  [1, 2, 3, 4, 5, 6]        2
    1  (0, 5)           [1, 4, 9]        2
    2  (0, 4)             [9, 11]        0
    

    性能在测试数据中:

    #30k rows
    df = pd.concat([df] * 10000, ignore_index=True)
    
    In [67]: %timeit [sum(a <= i <= b for i in y) for (a, b), y in df[['t','l']].to_numpy()]
    65.3 ms ± 1.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [68]: %timeit [len(set(range(a, b+1)).intersection(y)) for (a, b), y in df[['t','l']].to_numpy()]
    60.7 ms ± 520 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

    • @jezrael 如果我想获取实际值(而不仅仅是计数器)?
    • @jezrael 带有 set.intersection 的方法对我不起作用,我得到:TypeError: 'float' 对象不能被解释为整数。只有第一个解决方案有效。
    • @okuoub - 使用df['counter'] = [[i for i in y if a &lt;= i &lt;= b] for (a, b), y in df[['t','l']].to_numpy()]
    猜你喜欢
    • 1970-01-01
    • 2016-04-22
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2018-06-22
    • 2022-01-12
    相关资源
    最近更新 更多