pandas:单独对每列排序
我的数据框看起来像这样,只是要大得多。
d = {'Col_1' : pd.Series(['A', 'B']),
'Col_2' : pd.Series(['B', 'A', 'C']),
'Col_3' : pd.Series(['B', 'A']),
'Col_4' : pd.Series(['C', 'A', 'B', 'D']),
'Col_5' : pd.Series(['A', 'C']),}
df = pd.DataFrame(d)
Col_1 Col_2 Col_3 Col_4 Col_5
A B B C A
B A A A C
NaN C NaN B NaN
NaN NaN NaN D NaN
首先,我想单独对每一列进行排序。我试着用类似这样的代码:df.sort([lambda x: x in df.columns], axis=1, ascending=True, inplace=True)
,但是结果总是出错。我该怎么做才能单独对每一列进行排序,最后得到像这样的结果:
Col_1 Col_2 Col_3 Col_4 Col_5
A A A A A
B B B B C
NaN C NaN C NaN
NaN NaN NaN D NaN
其次,我想把每一列中的行连接起来。
df = pd.concat([df,pd.DataFrame(df.sum(axis=0),columns=['Concatenation']).T])
我可以用上面的代码把所有内容结合起来,前提是把np.nan替换成'',但是结果会变得很混乱(像'AB'这样连在一起),还需要额外的步骤来整理成像'A:B'这样的格式。
5 个回答
我不知道这样是否更好,不过这里有几种其他的方法可以做到这一点。
pd.DataFrame({key: sorted(value.values(), reverse=True) \
for key, value in df.to_dict().iteritems()})
pd.DataFrame({key: sorted(values, reverse=True) \
for key, values in df.transpose().iterrows()})
另一种解决方案是:
df.apply(lambda x: x.sort_values().reset_index(drop=True), axis=0)
(感谢 @BrenBarn 提到的 reset_index
。)
根据 @Andy Hayden 的评论,使用 values
而不是 reset_index
可以得到:
df.apply(lambda x: x.sort_values().values, axis=0)
如果你的数据是数字类型,你可以使用Numpy的排序功能:
df[:] = np.sort(df.values)
但是在你的情况下,这个方法不行,因为它无法处理浮点数和字符串混合的数据。
这里有一个解决办法:
df[:] = np.sort(df.fillna('\xff\xff\xff').values)
df = df.replace('\xff\xff\xff', np.nan)
我把NaN(缺失值)替换成一个ASCII值为255的字符字符串,这样在排序后它们几乎肯定会排到最后。然后再把它们替换回NaN。
输出结果:
Col_1 Col_2 Col_3 Col_4 Col_5
0 A A B B C
1 A A A B C
2 B C NaN NaN NaN
3 D NaN NaN NaN NaN
pandas.Series.order
从 pandas 0.17 版本开始就不再推荐使用了。 现在应该使用 sort_values
,用法如下:
for col in df:
df[col] = df[col].sort_values(ignore_index=True)
这里有一种方法:
>>> pandas.concat([df[col].order().reset_index(drop=True) for col in df], axis=1, ignore_index=True)
11: 0 1 2 3 4
0 A A A A A
1 B B B B C
2 NaN C NaN C NaN
3 NaN NaN NaN D NaN
[4 rows x 5 columns]
不过,你的做法有点奇怪。DataFrame并不是一堆没有关系的列。在一个DataFrame中,每一行代表一条记录,所以一列中的值和同一行中其他列的值是有联系的。如果你独立地对列进行排序,就会丢失这些信息,这样行的数据就变得没有意义了。这就是为什么在我的例子中需要使用reset_index
的原因。此外,正因为如此,你的例子中提到的想要就地处理(in-place)也是做不到的。