我的 pandas DataFrame 选择没有错误吗?

Posted

技术标签:

【中文标题】我的 pandas DataFrame 选择没有错误吗?【英文标题】:Is my pandas DataFrame selection bug-free? 【发布时间】:2017-05-30 07:46:58 【问题描述】:

我有一个非常大的星系群目录,还有一个来自 Zoo Universe 项目的形态。我做了一个外连接,所以我现在有一个 DataFrame,其中有一列“Morph”,其中可以有 NaN(来自外连接)、“U”(未知的 Galaxy Zoo 代码)或适当的值。

现在我正在寻找已知所有形态的组(即具有相同“组”值的行)。不幸的是,当我运行我的代码时,它没有找到,这对我来说非常难过,但可能(我无法在 15 分钟的数据检查中找到一个例子,但这不是一个证明,考虑到大小目录)。

问题是:我的代码没有错误吗?

这是一个模拟示例:

df= pd.DataFrame(data=[[1,'S'],[1,'E'],[1,'E'],[2,'U'],[2,'E'],[2,'S'],[3,np.nan],
                       [3,'E'],[3,'E'],[4,'U'],[4,'U'],[4,'U']], columns=['Group','Morph'])

df

还有我的代码:

df.groupby('Group').filter(lambda x: (~x.Morph.isin(['U',np.nan]).any() ))

这似乎在这里工作:

第一组是唯一没有 NaN 和 'U' 的组。是否有可能它偶然在这里工作并且我的代码中有一个错误在我的简单示例中不会显示出来?

【问题讨论】:

完成 groupby 后,您应该可以按组访问表格:df.groupby('Group').all().T['group name'] 如果您在此处找到元素但在过滤操作后没有,则可能是后者的问题... 我不太确定是否理解您的回答,但我会尝试对其进行调查。我已经在 csv 中导出了数据,以便能够通过肉眼查找组,但没有成功 - 尽管如此,如前所述,由于目录大小,我无法确定。 @Matt - 我认为您的代码看起来不错,print (df.groupby('Group')['Morph'].filter(lambda x: (~x.isin(['U',np.nan]).any()))) 可能会有所改进。我添加了另一个测试解决方案,但数据中似乎有些问题(空格' U' 不是'U')。 【参考方案1】:

我认为您的解决方案效果很好,我添加了没有groupby 的替代解决方案,带有双booelan indexingisin

print (df[df['Morph'].isin(['U',np.nan])])
    Group Morph
3       2     U
6       3   NaN
9       4     U
10      4     U
11      4     U

#unique is for faster isin if check unique values
idx = df.loc[df['Morph'].isin(['U',np.nan]), 'Group'].unique()
print (idx)
[2 3 4]

print (df[~df['Group'].isin(idx)])
   Group Morph
0      1     S
1      1     E
2      1     E

一行解决方案:

print (df[~df['Group'].isin(df.loc[df['Morph'].isin(['U',np.nan]), 'Group'].unique())])
   Group Morph
0      1     S
1      1     E
2      1     E

比较解决方案 - 存在很大差异 - groupby 解决方案要慢 100 倍,但主要取决于您的真实数据:

np.random.seed(123)
#1M df
N = 1000000
L2 = ['S','E','U',np.nan]
df = pd.DataFrame('Group':np.random.randint(100000, size=N), 
                   'Morph': np.random.choice(L2, N))

#print (df)

In [46]: %timeit (df[~df['Group'].isin(df.loc[df['Morph'].isin(['U',np.nan]), 'Group'].unique())])
1 loop, best of 3: 372 ms per loop

In [47]: %timeit (df.groupby('Group').filter(lambda x: (~x.Morph.isin(['U',np.nan]).any() )))
1 loop, best of 3: 34.7 s per loop

【讨论】:

非常感谢。由于我使用大目录,100 倍的时差可以改变我的生活,谢谢! :)

以上是关于我的 pandas DataFrame 选择没有错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

pandas报错处理:TypeError: Empty 'DataFrame': no numeric data to plot

Python Pandas Dataframe 合并并只选择几列

按标签选择的 Pandas 有时会返回 Series,有时会返回 DataFrame

通过从每一行的不同列中选择一个元素,从 Pandas DataFrame 创建一个系列

选择每第 n 行作为 Pandas DataFrame 而无需读取整个文件

使用 pandas dataframe.query() 选择列