pandas系列可以作为列而非行吗?
这个问题看起来可能有点小题大做,但其实是个真实的问题。简单来说,我想把一个序列当作一列来处理,而不是一行。我觉得这样更直观,尽管从技术上讲,序列不能被严格划分为行和列,但一维的numpy数组是可以的。下面是个例子:
df = pd.DataFrame( { 'a' : [5,3,1],
'b' : [4,6,2],
'c' : [2,4,9] } )
df['rowsum'] = df.sum(1)
In [31]: df
Out[31]:
a b c rowsum
0 5 4 2 11
1 3 6 4 13
2 1 2 9 12
我只是想按行计算百分比(也就是说每一行的总和为1)。我想这样做:
df.iloc[:,0:3] / df.rowsum
在numpy中,这样做是没问题的(通过reshape),因为你可以把行总和变成列向量或行向量。但在这里,我不能对序列进行reshape,也不能对df.rowsum使用T。看起来数据框(dataframe)可以转置,但序列(series)却不行。下面的代码可以正常工作(还有其他几种解决方案)。在numpy中可以很自然地实现,但那样就需要先转换成数组,然后再转换回数据框。
In [32]: ( df.iloc[:,0:3].T / df.rowsum ).T
Out[32]:
a b c
0 0.454545 0.363636 0.181818
1 0.230769 0.461538 0.307692
2 0.083333 0.166667 0.750000
如果这看起来很简单,我感到抱歉,但能够以直观的方式在代码中处理行和列是很重要的。所以我的问题就是:我能否让一个序列像列向量一样工作,而不是像行向量那样?
另外,似乎在列上这样做是没问题的,这让我觉得不太一致。
df.iloc[:,0] / df.rowsum
在这种情况下,pandas似乎是在对两个列数组进行逐元素的除法(因为显示的方式,即使行和列的区分是人为的)。但是当这个表达式的第一部分从数据框变成序列时,它似乎就从3x1变成了1x2。就像从序列变成数据框是一个隐式的转换操作?
也许换个角度思考会更好:
all( dist.iloc[:,:10].index == dist.rowsum.index )
Out[1526]: True
这里的索引是对齐的,为什么pandas在序列/序列广播和数据框/序列广播时似乎对索引的处理不同?还是说我完全想错了?!
2 个回答
1
试试看
df.iloc[:, 0:3].div(df.rowsum, axis=0)
看看这是不是你想要的。
2
试试这个
df.apply(lambda x:x/x[3], axis = 1)
a b c rowsum
0 0.454545 0.363636 0.181818 1
1 0.230769 0.461538 0.307692 1
2 0.083333 0.166667 0.750000 1
如果你不需要行总和这一列,可以使用
df.apply(lambda x:x/sum(x), axis = 1) #with your original dataFrame