检查元素的pandas数据帧的最快方法是什么?

时间:2017-12-20 10:09:01

标签: python python-3.x pandas dataframe

我对检查项目的pandas数据帧列的最佳方法感到困惑。

我正在编写一个程序,如果数据框中某个列中的元素不允许,则会引发错误。

以下是一个例子:

import pandas as pd

raw_data = {'first_name': ['Jay', 'Jason', 'Tina', 'Jake', 'Amy'], 
        'last_name': ['Jones', 'Miller', 'Ali', 'Milner', 'Cooze'], 
        'age': [47, 42, 36, 24, 73], 
        'preTestScore': [4, 4, 31, 2, 3],
        'postTestScore': [27, 25, 57, 62, 70]}
df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'preTestScore', 'postTestScore'])
print(df)

输出

  first_name last_name  age  preTestScore  postTestScore
0      Jay       Jones   47             4             27
1      Jason    Miller   42             4             25
2       Tina       Ali   36            31             57
3       Jake    Milner   24             2             62
4        Amy     Cooze   73             3             70

如果列last_name包含JonesMillerAliMilnerCooze以外的任何内容,请发出警告。

有人可能会使用pandas.DataFrame.isin,但我不清楚这是最有效的方法。

类似的东西:

if df.isin('last_name':{'Jones', 'Miller', 'Ali', 'Milner', 'Cooze'}).any() == False:
    raise:
        ValueError("Column `last_name` includes ill-formed elements.")

2 个答案:

答案 0 :(得分:2)

我认为如果匹配所有值,您可以使用all进行检查:

if not df['last_name'].isin(['Jones', 'Miller', 'Ali', 'Milner', 'Cooze']).all():
    raise ValueError("Column `last_name` includes ill-formed elements.")

issubset的另一种解决方案:

if not set(['Jones', 'Miller', 'Ali', 'Milner', 'Cooze']).issubset(df['last_name']):
    raise ValueError("Column `last_name` includes ill-formed elements.")

<强>计时

np.random.seed(123)
N = 10000
L = list('abcdefghijklmno') 

df = pd.DataFrame({'last_name': np.random.choice(L, N)})
print (df)

In [245]: %timeit df['last_name'].isin(L).all()
The slowest run took 4.73 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 421 µs per loop

In [247]: %timeit set(L).issubset(df['last_name'])
The slowest run took 4.50 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 273 µs per loop

In [248]: %timeit df.loc[~df['last_name'].isin(L), 'last_name'].any()
1000 loops, best of 3: 562 µs per loop

<强>买者

性能实际上取决于数据 - 行数和非匹配值的数量。

答案 1 :(得分:2)

您可以使用loc

if df.loc[~df['last_name'].isin({'Jones', 'Miller', 'Ali', 'Milner', 'Cooze'}), 'last_name'].any():
    raise ValueError("Column `last_name` includes ill-formed elements.")

这将检查last_name中除了指定的值之外是否还有其他值。