我有以下示例数据框:
N = np.arange(1, 10)
df = pd.DataFrame({
'ref': [ 'a', 'b', 'c', 'd', 'c', 'b', 'a', 'b', 'c'],
'a': [ 1, 2, 3, 4, 5, 6, 7, 8, 9],
'b': [ 10, 20, 30, 40, 50, 60, 70, 80, 90],
'c': [ 100, 200, 300, 400, 500, 600, 700, 800, 900],
'd': [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000],
})
我想以某种方式“取消引用” ref
列以获取此信息:
'ref': [ 'a', 'b', 'c', 'd', 'c', 'b', 'a', 'b', 'c'],
'ind': [ 1, 20, 300, 4000, 500, 60, 7, 80, 900],
因此ind
中的每个值都应与ref
标记的列中的值在同一位置对应。
朴素的方法是使用类似df[df['ref']]
的东西,然后乘以单位矩阵,然后按列求和。但是,由于我有很大的(〜8 GB)数据帧,因此我猜这样做会使其大小几乎平方。而且感觉不对。
此外,由于大小的原因,它的迭代速度非常慢。而且我无法使用Cython进行迭代,因为将此数据帧转换为numpy数组会丢失标签信息,而我需要正确地找到该列。
有什么建议吗?..
答案 0 :(得分:1)
您可以使用DataFrame.mask
或numpy进行操作,如下图所示numpy在此数据集中的效果要好一些
N = np.arange(1, 10)
df_b = pd.DataFrame({
'ref': [ 'a', 'b', 'c', 'd', 'c', 'b', 'a', 'b', 'c'],
'a': [ 1, 2, 3, 4, 5, 6, 7, 8, 9],
'b': [ 10, 20, 30, 40, 50, 60, 70, 80, 90],
'c': [ 100, 200, 300, 400, 500, 600, 700, 800, 900],
'd': [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000],
})
df_b
在哪里使用熊猫
%%timeit
df = df_b.copy()
cols = df.columns[1:]
df["ind"] = df["ref"]
for col in cols:
df.ind.mask(df.ind==col, df[col], inplace=True)
df
## 6.73 ms ± 129 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
使用Numpy的位置
%%timeit
df = df_b.copy()
arr = df.ref.values
cols = df.columns[1:]
for col in cols:
arr2 = df[col].values
arr = np.where(arr==col, arr2, arr)
df["ind"] = arr
df
## 1.21 ms ± 73 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
结果
ref a b c d ind
0 a 1 10 100 1000 1
1 b 2 20 200 2000 20
2 c 3 30 300 3000 300
3 d 4 40 400 4000 4000
4 c 5 50 500 5000 500
5 b 6 60 600 6000 60
6 a 7 70 700 7000 7
7 b 8 80 800 8000 80
8 c 9 90 900 9000 900
答案 1 :(得分:0)
使用pandas.lookup()
df['ind'] = df.lookup(df.index, df['ref'])
ref a b c d ind
0 a 1 10 100 1000 1
1 b 2 20 200 2000 20
2 c 3 30 300 3000 300
3 d 4 40 400 4000 4000
4 c 5 50 500 5000 500
5 b 6 60 600 6000 60
6 a 7 70 700 7000 7
7 b 8 80 800 8000 80
8 c 9 90 900 9000 900
答案 2 :(得分:0)
您可以使用numpy索引:
lookup = dict(zip(df.columns, range(len(df.columns))))
result = pd.DataFrame({ 'ref' : df.ref, 'ind': df.values[np.arange(len(df)), df.ref.map(lookup)] })
print(result)
输出
ref ind
0 a 1
1 b 20
2 c 300
3 d 4000
4 c 500
5 b 60
6 a 7
7 b 80
8 c 900