我有一个如下数据框
A_Name B_Detail Value_B Value_C Value_D ......
0 AA X1 1.2 0.5 -1.3 ......
1 BB Y1 0.76 -0.7 0.8 ......
2 CC Z1 0.7 -1.3 2.5 ......
3 DD L1 0.9 -0.5 0.4 ......
4 EE M1 1.3 1.8 -1.3 ......
5 FF N1 0.7 -0.8 0.9 ......
6 GG K1 -2.4 -1.9 2.1 ......
这只是数据框的一个示例,我可以有n个列,如(Value_A,Value_B,Value_C,........... Value_N)
现在我想过滤所有列的绝对值(Value_A,Value_B,Value_C,....)小于1的所有行。
如果您的列数有限,则可以通过简单地添加'和'来过滤数据。数据框中的列上的条件,但我无法弄清楚在这种情况下要做什么。
我不知道这些列的数量是多少,我唯一知道这些列的前缀是'值'。
在上面的情况下,输出应该像
A_Name B_Detail Value_B Value_C Value_D ......
1 BB Y1 0.76 -0.7 0.8 ......
3 DD L1 0.9 -0.5 0.4 ......
5 FF N1 0.7 -0.8 0.9 ......
答案 0 :(得分:4)
使用filter
与abs
和all
一起创建mask
,然后boolean indexing
:
mask = (df.filter(like='Value').abs() < 1).all(axis=1)
print (mask)
0 False
1 True
2 False
3 True
4 False
5 True
6 False
dtype: bool
print (df[mask])
A_Name B_Detail Value_B Value_C Value_D
1 BB Y1 0.76 -0.7 0.8
3 DD L1 0.90 -0.5 0.4
5 FF N1 0.70 -0.8 0.9
时间中的所有组合:
#len df = 70k, 5 columns
df = pd.concat([df]*10000).reset_index(drop=True)
In [47]: %timeit (df[(df.filter(like='Value').abs() < 1).all(axis=1)])
100 loops, best of 3: 7.48 ms per loop
In [48]: %timeit (df[df.filter(regex=r'Value').abs().lt(1).all(1)])
100 loops, best of 3: 7.02 ms per loop
In [49]: %timeit (df[df.filter(like='Value').abs().lt(1).all(1)])
100 loops, best of 3: 7.02 ms per loop
In [50]: %timeit (df[(df.filter(regex=r'Value').abs() < 1).all(axis=1)])
100 loops, best of 3: 7.3 ms per loop
#len df = 70k, 5k columns
df = pd.concat([df]*10000).reset_index(drop=True)
df = pd.concat([df]*1000, axis=1)
#only for testing, create unique columns names
df.columns = df.columns.str[:-1] + [str(col) for col in list(range(df.shape[1]))]
print (df)
In [75]: %timeit ((df[(df.filter(like='Value').abs() < 1).all(axis=1)]))
1 loop, best of 3: 10.3 s per loop
In [76]: %timeit ((df[(df.filter(regex=r'Value').abs() < 1).all(axis=1)]))
1 loop, best of 3: 10.3 s per loop
In [77]: %timeit (df[df.filter(regex=r'Value').abs().lt(1).all(1)])
1 loop, best of 3: 10.4 s per loop
In [78]: %timeit (df[df.filter(like='Value').abs().lt(1).all(1)])
1 loop, best of 3: 10.1 s per loop
答案 1 :(得分:4)
filter
获取您关注的列。abs().lt(1)
以查找小于1的单元格。all(1)
查找所有Value
小于1的行。df[df.filter(regex=r'Value').abs().lt(1).all(1)]
<强>结论强>
like
比regex
快
lt
比<
最快的解决方案是两者兼顾:
df[df.filter(like='Value').abs().lt(1).all(1)]
<强>击穿强>
答案 2 :(得分:0)
如果您不想过滤列名称(即使它们带有前缀),您也可以使用ix
:
>>> df[df.ix[:,2:].abs().lt(1).all(1)]
A_Name B_Detail Value_B Value_C Value_D
1 BB Y1 0.76 -0.7 0.8
3 DD L1 0.90 -0.5 0.4
5 FF N1 0.70 -0.8 0.9
这假设所有“值”列都在“详细”列之后。
既然每个人都在进行基准测试,那就更快了:
In [7]: %timeit df[df.ix[:,2:].abs().lt(1).all(1)]
1000 loops, best of 3: 803 µs per loop
In [8]: %timeit df[df.filter(like='Value').abs().lt(1).all(1)]
1000 loops, best of 3: 939 µs per loop
答案 3 :(得分:0)
您可以使用str.contains匹配列,然后将apply()与lambda
一起使用:
cols = df.columns[df.columns.str.contains('Value')]
df[df[cols].apply(lambda x: abs(x) < 1).sum(axis=1) == len(cols)]
输出:
A_Name B_Detail Value_B Value_C Value_D
1 BB Y1 0.76 -0.7 0.8
3 DD L1 0.90 -0.5 0.4
5 FF N1 0.70 -0.8 0.9