2024-09-29 23:18:50 发布
网友
我有这样一个数据帧(简化示例)
id v0 v1 v2 v3 v4 1 10 5 10 22 50 2 22 23 55 60 50 3 8 2 40 80 110 4 15 15 25 100 101
并希望创建一个1或0的附加列。如果v0值在v1到v4之间,则为1;如果不是,则为0。因此,在这个例子中,对于id 1,值应该是1(因为v2=10),对于id 2,值应该是0,因为22不在v1到v4中。在
实际上,这个表要大得多(大约100000行和变量从v1到v99)。在
怎么样:
df['new_col'] = df.loc[:, "v1":].eq(df['v0'],0).any(1).astype(int)
[出去]
您可以使用底层numpy数组来提高性能:
numpy
设置
a = df.v0.values b = df.iloc[:, 2:].values
id v0 v1 v2 v3 v4 out 0 1 10 5 10 22 50 1 1 2 22 23 55 60 50 0 2 3 8 2 40 80 110 0 3 4 15 15 25 100 101 1
此解决方案利用广播进行成对比较:
首先,我们广播a:
a
>>> a[:, None] array([[10], [22], [ 8], [15]], dtype=int64)
允许与b成对比较:
b
>>> a[:, None] == b array([[False, True, False, False], [False, False, False, False], [False, False, False, False], [ True, False, False, False]])
然后,我们只需检查沿第一个轴的True结果,并将其转换为整数。在
True
性能
功能
def user_chris(df): a = df.v0.values b = df.iloc[:, 2:].values return (a[:, None]==b).any(1).astype(int) def rahlf23(df): df = df.set_index('id') return df.drop('v0', 1).isin(df['v0']).any(1).astype(int) def chris_a(df): return df.loc[:, "v1":].eq(df['v0'], 0).any(1).astype(int) def chris(df): return df.apply(lambda x: int(x['v0'] in x.values[2:]), axis=1) def anton_vbr(df): df.set_index('id', inplace=True) return df.isin(df.pop('v0')).any(1).astype(int)
import pandas as pd import numpy as np import matplotlib.pyplot as plt from timeit import timeit res = pd.DataFrame( index=['user_chris', 'rahlf23', 'chris_a', 'chris', 'anton_vbr'], columns=[10, 50, 100, 500, 1000, 5000], dtype=float ) for f in res.index: for c in res.columns: vals = np.random.randint(1, 100, (c, c)) vals = np.column_stack((np.arange(vals.shape[0]), vals)) df = pd.DataFrame(vals, columns=['id'] + [f'v{i}' for i in range(0, vals.shape[0])]) stmt = '{}(df)'.format(f) setp = 'from __main__ import df, {}'.format(f) res.at[f, c] = timeit(stmt, setp, number=50) ax = res.div(res.min()).T.plot(loglog=True) ax.set_xlabel("N"); ax.set_ylabel("time (relative)"); plt.show()
输出
另一个例子,很可能是最小的语法:
df['new'] = df.isin(df.pop('v0')).any(1).astype(int)
充分证明:
退货:
v1 v2 v3 v4 new id 1 5 10 22 50 1 2 23 55 60 50 0 3 2 40 80 110 0 4 15 25 100 101 1
怎么样:
[出去]
^{pr2}$您可以使用底层
numpy
数组来提高性能:设置
^{pr2}$
此解决方案利用广播进行成对比较:
首先,我们广播
a
:允许与
b
成对比较:然后,我们只需检查沿第一个轴的
True
结果,并将其转换为整数。在性能
功能
设置
输出
另一个例子,很可能是最小的语法:
充分证明:
^{pr2}$退货:
相关问题 更多 >
编程相关推荐