我有这个pd.Series
:
s = pd.Series([1, 'a', 1.4, 'b', 4, 98, 6.7, 'hello', 98.9])
我的目标是将每个值类型的值以相反的顺序交换。
我想要的输出是:
>>> s = pd.Series([98, 'hello', 98.9, 'b', 4, 1, 6.7, 'a', 1.4])
>>> s
0 98
1 hello
2 98.9
3 b
4 4
5 1
6 6.7
7 a
8 1.4
dtype: object
>>>
正如您所看到的,不同的值类型仍然是混合顺序的,但是它们被其他相同类型的值颠倒了。
整数顺序是
1, 4, 98
,现在是98, 4, 1
。浮动顺序是
1.4, 6.7, 98.9
,现在是98.9, 6.7, 1.4
。字符串顺序是
'a', 'b', 'hello'
,现在是'hello', 'b', 'a'
目前为止我所尝试的是:
>>> s.to_frame().groupby([[*map(type, s)]], sort=False).apply(lambda x: x.iloc[::-1]).reset_index(drop=True)
0
0 98
1 4
2 1
3 hello
4 b
5 a
6 98.9
7 6.7
8 1.4
>>>
是的,它们的顺序是颠倒的。但是,由于我使用的是groupby
,这些值被分组到单独的组中,它们不会混合在一起。
我该如何解决这个问题?
out = (s.groupby(s.map(type), sort=False)
.apply(lambda x: pd.Series(x.sort_values(ascending=False).tolist(), index=x.index)))
out
0 98
1 hello
2 98.9
3 b
4 4
5 1
6 6.7
7 a
8 1.4
dtype: object
我刚刚想出了一个解决方案,它有点长,效率低。不过我还是希望有更好的解决方案。
我是这样做的:
print(
s.to_frame().groupby([[*map(type, s)]], sort=False)
.apply(lambda x: x.reindex(x.index[::-1])
.rename(index=dict(zip(x.index[::-1], x.index))))
.reset_index(level=0, drop=True)
.sort_index().squeeze().rename(index=None)
)
输出:
0 98
1 hello
2 98.9
3 b
4 4
5 1
6 6.7
7 a
8 1.4
dtype: object
我使用to_frame
将这个Series
转换为DataFrame
,我使用map
给我所有值的类型。之后,我使用groupby
对它们进行分组,apply
和rename
将它们的顺序/索引颠倒。下一步是使用reset_index
重置索引,并使用sort_index
按索引对值排序。然后,我只使用squeeze
将此DataFrame
再次转换为Series
,并使用rename
删除索引名称。