我有一个包含许多列的数据框,并且我想以规则的列间隔将其除以另一个数据框,以最小的内存使用量。
例如:
df1 = pd.DataFrame([[1,2,3,4,5,6,7,8,9,10], [10,9,8,7,6,5,4,3,2,1], [2,4,3,1,6,5,7,8,9,4]])
df2 = pd.DataFrame([[1,3],[7,6],[9,3]])
我想每两列间隔将df1除以df2多次。我想要的结果是:
finalDf = pd.DataFrame([[1/1,2/3,3/1,4/3,5/1,6/3,7/1,8/3,9/1,10/3], [10/7,9/6,8/7,7/6,6/7,5/6,4/7,3/6,2/7,1/6], [2/9,4/3,3/9,1/3,6/9,5/3,7/9,8/3,9/9,4/3]])
我认为代码看起来像这样:
df3 = df1.iloc[:, 0:2].divide(df2.iloc[:,:].values, axis = 'rows')
df4 = df1.iloc[:, 2:4].divide(df2.iloc[:,:].values, axis = 'rows')
df5 = df1.iloc[:, 4:6].divide(df2.iloc[:,:].values, axis = 'rows')
df6 = df1.iloc[:, 6:8].divide(df2.iloc[:,:].values, axis = 'rows')
finalDf = pd.concat([df3, df4, df5, df6], axis=1)
我想实现这样的事情的唯一方法就是将其循环,但是我觉得那不是明智的选择。有办法矢量化解决方案吗?
答案 0 :(得分:2)
pd.concat
:res = pd.concat([df2]*5, 1)
res.columns = df1.columns
df1/res
0 1 2 3 ... 6 7 8 9
0 1.000000 0.666667 3.000000 1.333333 ... 7.000000 2.666667 9.000000 3.333333
1 1.428571 1.500000 1.142857 1.166667 ... 0.571429 0.500000 0.285714 0.166667
2 0.222222 1.333333 0.333333 0.333333 ... 0.777778 2.666667 1.000000 1.333333
概括:
res = pd.concat([df2]*(df1.shape[1]//df2.shape[1]), 1)
答案 1 :(得分:2)
假设列为数字列,则可以通过重新标记df1
的列以模仿df2
的列,来欺骗熊猫执行索引对齐的划分。
df1.columns = np.tile(df2.columns, df1.shape[1] // df2.shape[1])
# A little more trickery to restore the ordering later.
ordering = df1.columns.values.argsort(kind='mergesort').argsort()
print (df1)
0 1 0 1 0 1 0 1 0 1
0 1 2 3 4 5 6 7 8 9 10
1 10 9 8 7 6 5 4 3 2 1
2 2 4 3 1 6 5 7 8 9 4
print (df2)
0 1
0 1 3
1 7 6
2 9 3
result = df1.div(df2).iloc[:, ordering]
这不会产生任何额外的数据。
答案 2 :(得分:1)
for c in df1:
df1[c] /= df2[c % 2].values # added .values to try and quicken it up a bit
df1.round(4)
0 1 2 3 4 5 6 7 8 9
0 1.0000 0.6667 3.0000 1.3333 5.0000 2.0000 7.0000 2.6667 9.0000 3.3333
1 1.4286 1.5000 1.1429 1.1667 0.8571 0.8333 0.5714 0.5000 0.2857 0.1667
2 0.2222 1.3333 0.3333 0.3333 0.6667 1.6667 0.7778 2.6667 1.0000 1.3333
from itertools import cycle
for i, j in zip(df1, cycle(df2)):
df1[i] /= df2[j].values
df1.round(4)
0 1 2 3 4 5 6 7 8 9
0 1.0000 0.6667 3.0000 1.3333 5.0000 2.0000 7.0000 2.6667 9.0000 3.3333
1 1.4286 1.5000 1.1429 1.1667 0.8571 0.8333 0.5714 0.5000 0.2857 0.1667
2 0.2222 1.3333 0.3333 0.3333 0.6667 1.6667 0.7778 2.6667 1.0000 1.3333