Python 如何删除0';s将数据帧转换为记录
我正在寻找一种有效的方法,从从Python 如何删除0';s将数据帧转换为记录,python,pandas,Python,Pandas,我正在寻找一种有效的方法,从从pd创建的字典列表中删除零。DataFrame以以下示例为例: df = pd.DataFrame([[1, 2], [0, 4]], columns=['a', 'b'], index=['x', 'y']) df.to_dict('records') [{'a': 1, 'b': 2}, {'a': 0, 'b': 4}] 我想要的是: [{'a': 1, 'b': 2}, {'b': 4}] 我有一个非常大的稀疏数据帧,存储所有的零是低效的。由于数据帧很
pd创建的字典列表中删除零。DataFrame
以以下示例为例:
df = pd.DataFrame([[1, 2], [0, 4]], columns=['a', 'b'], index=['x', 'y'])
df.to_dict('records')
[{'a': 1, 'b': 2}, {'a': 0, 'b': 4}]
我想要的是:
[{'a': 1, 'b': 2}, {'b': 4}]
我有一个非常大的稀疏数据帧,存储所有的零是低效的。由于数据帧很大,我正在寻找一种比在字典的数据帧中循环并删除零更快的解决方案,例如,下面的方法虽然有效,但速度非常慢,并且占用大量内存
new_records = []
for record in df.to_dict('records'):
new_records.append(dict((k, v) for k, v in record.items() if v))
有没有更有效的方法或途径 使用列表理解
[r[r != 0].to_dict() for _, r in df.iterrows()]
[{'a': 1, 'b': 2}, {'b': 4}]
这似乎是一个x-y问题:只需使用稀疏矩阵表示。唯一的困难是您必须自己跟踪专栏:
In [8]: from scipy import sparse
In [9]: df
Out[9]:
a b
x 1 2
y 0 4
In [10]: column_names = df.columns
In [11]: sm = sparse.csc_matrix(df.values)
或者,更简单,正如piRSquared所指出的,pandas
内置此功能:
df.to_sparse(0)
如果出于某种原因,您决定跳过稀疏的想法(好主意),并且您确实想要一个字典列表,比如从
pd.Dataframe
生成的字典,但缺少零,那么您可以尝试使用numpy.flatnonzero()
和numpy索引来解决这个问题。我做了一些快速测试,它看起来比您建议的版本快,但不知道差异是否显著
import numpy as np
new_records = []
columns=np.array(df.columns.values)
for record in df.as_matrix():
idx=np.flatnonzero(record)
new_records.append( dict( zip( columns[idx], record[idx] ) ) )
输出是您要求的输出:
[{'a': 1, 'b': 2}, {'b': 4}]
细节:
- 首先检索要用作每个新字典键的列值,并使它们成为numpy数组,以使用numpy数组索引
np.array(df.columns.values)
- 接下来,将数据帧转换为numpy矩阵
df.as\u matrix()
- 对于每条记录,获取不带零的位置的索引
np.flatnonzero()
- 使用列和记录的切片版本制作字典。这里是使用索引的地方
dict(zip(列[idx],记录[idx]))
- 将每个新词典附加到新记录中
True
。。。你是否考虑过使用稀疏矩阵?我对稀疏表示不太熟悉,但我相信你是正确的,这将是一种更好的方法。我同意你的看法。然而,熊猫有它自己的稀疏df。为了_sparse(0)
@piRSquared-Welp,甚至更好!我试过这个,它似乎没有为我删除0值。我做错什么了吗?df.to_sparse(0).to_dict('records')@Kelvin如果您使用to_dict
它当然会返回零。你需要直接使用稀疏表示,我在这里遇到的问题是,将数据帧转换为稀疏表示非常非常缓慢。比使用for循环或类似方法将数据帧转换为不带零的字典慢得多。这是预期的吗?
[{'a': 1, 'b': 2}, {'b': 4}]