Python 检查数据帧元组中的值是否为
我有一个巨大的数据帧(38 milj行): 现在我想过滤掉Python 检查数据帧元组中的值是否为,python,pandas,performance,bigdata,Python,Pandas,Performance,Bigdata,我有一个巨大的数据帧(38 milj行): 现在我想过滤掉'F' 给予: C F I 0 80 (1, 2, 3, 4) 1 3 80 (4, 0, 8, 3, 2) 4 有没有一种高性能、低内存使用率的方法可以做到这一点 我尝试了np.equal((3),df['F'].values)。all(),但这显然不起作用如果性能很重要,请在列表理解中使用: df = df[[3 in x for x in df['F']]] 或:
'F'
给予:
C F I
0 80 (1, 2, 3, 4) 1
3 80 (4, 0, 8, 3, 2) 4
有没有一种高性能、低内存使用率的方法可以做到这一点
我尝试了
np.equal((3),df['F'].values)。all()
,但这显然不起作用如果性能很重要,请在列表理解中使用:
df = df[[3 in x for x in df['F']]]
或:
性能(取决于匹配值的数量以及df
的长度):
更好的结构,如pointed@jpp是create:
from itertools import chain
lens = df['F'].str.len()
df = pd.DataFrame({
'I' : df['I'].values.repeat(lens),
'C' : df['C'].values.repeat(lens),
'F' : list(chain.from_iterable(df['F'].tolist()))
})
print (df)
I C F
0 1 80 1
1 1 80 2
2 1 80 3
3 1 80 4
4 2 160 5
5 2 160 7
6 2 160 2
7 3 240 9
8 3 240 6
9 3 240 2
10 3 240 5
11 3 240 7
12 4 80 4
13 4 80 0
14 4 80 8
15 4 80 3
16 4 80 2
您应该通过传递lambda
表达式,将in
运算符与apply
方法结合使用
输出
I C F
0 1 80 (1, 2, 3, 4)
3 4 80 (4, 0, 8, 3, 2)
在loc
中简单应用即可实现此目的
df.loc[df.F.apply(lambda t : 3 in t)]
I C F
0 1 80 (1, 2, 3, 4)
3 4 80 (4, 0, 8, 3, 2)
有没有一种高性能、低内存使用率的方法可以做到这一点
不,没有。一系列元组没有矢量化。它由双层指针组成,不适合Pandas/NumPy。您可以使用诸如str
访问器或列表理解之类的hack。或者,甚至尝试扩展到数据帧:
mask = pd.DataFrame(df['F'].values.tolist()).eq(3).any(1)
print(mask)
0 True
1 False
2 False
3 True
dtype: bool
但所有这些都很昂贵。为了提高性能,您应该在构建系列之前改进数据的结构。谢谢大家,哪一个最快?我猜set
?@Ward-最快的是中的,我想是列表理解。@Ward-添加了推荐的数据结构-将元组展平到列,并重复I
和C
列。扩展的数据帧更像它。但最好的解决方案取决于阵列的粗糙程度。。。e、 你会在一个元组中得到1个值,而在另一个元组中得到100个值吗。如果您总是有3-5个值,我的解决方案可能会更好。如果它非常粗糙,那么耶斯雷尔的扩展版更好。@jpp-是的,我同意,这取决于真实数据。但是它不会在您的解决方案中创建NaN
s-like,而是重复行。实际上,它是一个int's('F')的列表,其成本('C')与索引('I')关联。是否有更好的方法来构造系列以提高性能?否,tuple
不会减少内存存储。NumPy数组通过避免使用指针和使用连续内存块来减少内存存储。因此,我应该将这些int列表放入NumPy数组,然后放入数据帧?如果您计划执行多个计算或存储数据,可以。事实上,如果你把它分解,我的解决方案就是这样做的。对于一次性的独立计算,jezrael的解决方案更好。不,我需要对存储的数据执行多个计算。
df[df['F'].apply(lambda x: 3 in x)]
I C F
0 1 80 (1, 2, 3, 4)
3 4 80 (4, 0, 8, 3, 2)
df.loc[df.F.apply(lambda t : 3 in t)]
I C F
0 1 80 (1, 2, 3, 4)
3 4 80 (4, 0, 8, 3, 2)
mask = pd.DataFrame(df['F'].values.tolist()).eq(3).any(1)
print(mask)
0 True
1 False
2 False
3 True
dtype: bool