给出Pandas DataFrame中的数据,如下所示:
Name Amount
---------------
Alice 100
Bob 50
Charlie 200
Alice 30
Charlie 10
Run Code Online (Sandbox Code Playgroud)
我想选择Name集合中几个值之一的所有行{Alice, Bob}
Name Amount
---------------
Alice 100
Bob 50
Alice 30
Run Code Online (Sandbox Code Playgroud)
在熊猫中这样做的有效方法是什么?
我看到的选项
选择并合并许多语句,如下所示
merge(df[df.name = specific_name] for specific_name in names) # something like this
Run Code Online (Sandbox Code Playgroud)执行某种连接
这里的表现权衡是什么?何时一种解决方案比其他方案更好?我错过了哪些解决方案?
虽然上面的示例使用字符串,但我的实际作业在数百万行上使用10-100个整数的匹配,因此快速的NumPy操作可能是相关的.
And*_*den 60
您可以使用isin Series方法:
In [11]: df['Name'].isin(['Alice', 'Bob'])
Out[11]:
0 True
1 True
2 False
3 True
4 False
Name: Name, dtype: bool
In [12]: df[df.Name.isin(['Alice', 'Bob'])]
Out[12]:
Name Amount
0 Alice 100
1 Bob 50
3 Alice 30
Run Code Online (Sandbox Code Playgroud)
由于在您的实际用例中,值df['Name']are ints,因此您可以使用NumPy索引而不是来更快地生成布尔掩码Series.isin。
idx = np.zeros(N, dtype='bool')
idx[names] = True
df[idx[df['Name'].values]]
Run Code Online (Sandbox Code Playgroud)
例如,给定此设置:
import pandas as pd
import numpy as np
N = 100000
df = pd.DataFrame(np.random.randint(N, size=(10**6, 2)), columns=['Name', 'Amount'])
names = np.random.choice(np.arange(N), size=100, replace=False)
Run Code Online (Sandbox Code Playgroud)
In [81]: %timeit idx = np.zeros(N, dtype='bool'); idx[names] = True; df[idx[df['Name'].values]]
100 loops, best of 3: 9.88 ms per loop
In [82]: %timeit df[df.Name.isin(names)]
10 loops, best of 3: 107 ms per loop
In [83]: 107/9.88
Out[83]: 10.82995951417004
Run Code Online (Sandbox Code Playgroud)
N是(基本上)df['Names']可以达到的最大值。如果N较小,则速度收益不会那么大。使用N = 200,
In [93]: %timeit idx = np.zeros(N, dtype='bool'); idx[names] = True; df[idx[df['Name'].values]]
10 loops, best of 3: 62.6 ms per loop
In [94]: %timeit df[df.Name.isin(names)]
10 loops, best of 3: 178 ms per loop
In [95]: 178/62.6
Out[95]: 2.8434504792332267
Run Code Online (Sandbox Code Playgroud)
注意:如上所示,似乎有速度上的好处,尤其是当速度N变大时。但是,如果N太大,则成型idx = np.zeros(N, dtype='bool')可能不可行。
完整性检查:
expected = df[df.Name.isin(names)]
idx = np.zeros(N, dtype='bool')
idx[names] = True
result = df[idx[df['Name'].values]]
assert expected.equals(result)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47834 次 |
| 最近记录: |