【问题标题】:Drop row if lambda returns None Pandas如果 lambda 返回 None 则删除行 Pandas
【发布时间】:2018-04-16 05:06:11
【问题描述】:
self.df['X'] = self.df['x'].apply(lambda x: my_map.get(x))

如何删除my_map.get(x) 返回None 的那些行。

我正在寻找一种解决方案,我不必再次遍历列来删除行。

谢谢

【问题讨论】:

  • 这是否意味着首先 i apply 然后运行 ​​dropna
  • 是的,完全正确。我认为不可能一步到位
  • 这听起来像是从 mymap 制作的数据框进行左连接可能会更好?

标签: python pandas


【解决方案1】:

我认为您需要dropna,因为可以在第一步中删除None,通过分配给新列创建NaNs:

self.df['X'] = self.df['x'].apply(lambda x: my_map.get(x))
self.df = self.df.dropna('X')

或者:

self.df = self.df[self.df['X'].notnull()]

【讨论】:

  • 我理解这个逻辑,但我担心因为我的一个df是250k行,这是6000万行中的一大块。
  • @RaheelKhan - 我添加了另一个解决方案,它是bit faster
  • 我怀疑,如果你问一个不同的问题,你会分享你想要对整个数据框做什么以及你的 lambda 是什么,你会得到一个更好的答案
  • 我尝试了 250k df,但没有任何区别。谢谢
  • @piRSquared my_map 只是一个字典,其中的键将是 x 我正在将该键的值分配给 X 一个新列。但由于数据量很大,会有很多 x 在我的 dict 中不匹配,所以我不想在我的 df 中找到这些记录。
【解决方案2】:

locpd.Series.compress 接受一个可调用参数并返回一个子集,其中可调用的计算结果为 True

compress

self.df['x'].compress(lambda x: my_map.get(x) is not None)

loc

self.df['x'].loc[lambda x: my_map.get(x) is not None]

【讨论】:

【解决方案3】:

你可以找到索引如下

idxs = self.df.index[self.df['X'].isnull()]  # find all indices with None in df.X

完整代码:

self.df['X'] = self.df['x'].apply(lambda x: my_map.get(x))
idxs = self.df.index[self.df['X'].isnull()]  # find all indices with None in df.X
self.df = self.df.drop(idxs)

【讨论】:

  • 你觉得self.df = self.df.dropna('X')这样会更优化吗?
  • self.df['X'] == None 返回 False :(
  • @jezrael 是的,你是对的。您可以使用 .isnull(),但我认为 self.df.dropna('X') 是更清洁的解决方案。
【解决方案4】:

如果您将 mymap 转换为字典,您可以将其作为合并来执行:

mymerge = pd.DataFrame.from_dict(mymap, orient = 'index')

然后使用左连接,只连接所需的列:

mymerge.merge(df, left_index = True, right_on = 'x')

一行:

pd.DataFrame.from_dict(mymap, orient = 'index').merge(df, left_index = True, right_on = 'x')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 2011-09-02
    • 2014-06-17
    • 2021-04-12
    • 2012-03-06
    • 2014-02-15
    • 1970-01-01
    相关资源
    最近更新 更多