以列表为值的 Pandas 单元格:删除列表中的 NA 值

时间:2021-07-12 10:43:56

标签: python pandas

我有一个 DataFrame,其中一些单元格具有 list() 类型的值。列表的某些元素是 numpy.nan。我想从该列表中删除 nan 元素。这是因为我想将列表的元素 str.join() 做一个字符串。

这是示例数据

   A         B
0  1    [a, b]
1  2  [c, nan]
2  3       [e]

结果应该是这样的:

   A       B
0  1  [a, b]
1  2     [c]
2  3     [e]

我的问题是我的解决方案是否合适,或者是否有更优雅的熊猫方式来做到这一点?

我知道一种解决方案可能是用其他东西替换 nan 值,例如一个空字符串``.但这不是那个场景的一部分。

这是 MWE

#!/usr/bin/env pyhton3
import pandas as pd
import numpy as np

# initial data
df = pd.DataFrame(
    {
        'A': [1, 1, 2, 2, 3],
        'B': ['a', 'b', 'c', np.nan, 'e']
    }
)

# create cells with list-values
df = df.groupby('A')['B'].agg(list)
df = df.reset_index()

print(df)

df.B = df.B.transform(lambda x: list(pd.Series(x).dropna()))

print(df)

# By the way:
# This was my goal but it is not possible with 'NA' values in the lists.
df.B = df.B.transform(lambda x: ' | '.join(x))

print(df)

2 个答案:

答案 0 :(得分:1)

如果存在缺失值的列表或 NaN 之类的 None,则在生成器推导式中删除 Nonetype

df.B = df.B.transform(lambda x: ' | '.join(y for y in x if pd.notna(y)))

或者,如果可能,删除 groupby 之前的缺失行:

df = df.dropna(subset=['B']).groupby('A')['B'].agg(' | '.join).reset_index()
print(df)
   A      B
0  1  a | b
1  2      c
2  3      e

答案 1 :(得分:1)

正如@jezrael 所提到的,您删除了生成器理解中的 NaN。

您也可以直接在 agg groupby 调用中执行此操作。

df = pd.DataFrame(
    {
        'A': [1, 1, 2, 2, 3],
        'B': ['a', 'b', 'c', np.nan, 'e']
    }
)

df = df.groupby('A')['B'].agg(lambda l: ' | '.join(x for x in l if pd.notna(x)))
相关问题