Python 快速将一系列标签从相应列转换为一系列间接值
我有以下数据帧示例:Python 快速将一系列标签从相应列转换为一系列间接值,python,pandas,dataframe,Python,Pandas,Dataframe,我有以下数据帧示例: 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
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
中的每个值都应该对应于同一位置标有fromref
的列中的值
天真的方法是使用类似于df[df['ref']]
,然后乘以单位矩阵,然后按列求和。但因为我有相当大的(~8GB)数据帧,所以我想这样做几乎可以使其大小平方。而且感觉不太对劲
另外,由于大小的原因,在它上面迭代的速度非常慢。我不能用Cython进行迭代,因为将这个数据帧转换成numpy数组会丢失标签信息,我需要正确地找到列
有什么建议吗?。您可以使用
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”:[100200300400500600700800900],
‘d’:[1000200030004000600070080009000],
})
德福
在以下位置使用熊猫
%%timeit
df=df_b.copy()
cols=df.columns[1:]
df[“ind”]=df[“ref”]
对于col中的col:
df.ind.mask(df.ind==col,df[col],inplace=True)
df
##每个回路6.73 ms±129µs(7次运行的平均值±标准偏差,每个100个回路)
在何处使用Numpy
%%timeit
df=df_b.copy()
arr=df.ref.values
cols=df.columns[1:]
对于col中的col:
arr2=df[col]。值
arr=np.其中(arr==col,arr2,arr)
df[“ind”]=arr
df
##每个回路1.21 ms±73µs(7次运行的平均值±标准偏差,每个1000个回路)
结果
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
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
使用pandas.lookup()
您可以使用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 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
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
这是一个简单的查找:
df['ind']=df.lookup(df.index,df['ref'])
YeahDataFrame的可能重复。查找是一个替代方法,但它有一个低效的循环Python实现。df['ind']=df.apply(lambda x:x[x['ref']],axis=1)
Yes-true,@ayhan它基本上是[df.get\u值(行,列)对于row,col in zip(row_标签,col_标签)
,请参阅我已修改了.mask
解决方案,以直接使用df['ref']==col
,因为标签和项目之间的值冲突可能性很大。它是性能最好的解决方案(每10万件物品8.86秒),而不是.apply(约2000秒)。非常感谢。好的,您已经使用numpy解决方案编辑了您的答案,根据您的基准测试,该解决方案更快。我也会检查一下。再次感谢你!选中,np.其中为每个循环3.64s(100kk项)。