pd.dataframe - 在不更改索引的情况下对列表列中的每个列表进行排序
Posted
技术标签:
【中文标题】pd.dataframe - 在不更改索引的情况下对列表列中的每个列表进行排序【英文标题】:pd.dataframe - sort each list in a column of lists without changing index 【发布时间】:2022-01-07 00:14:46 【问题描述】:如果我有这个 pandas v1.3.4 dataframe
:
index col1 col2
1 ['1','2','3'] 'a'
2 ['2','4','2'] 'b'
3 ['5','2','1'] 'c'
4 ['3','2','1'] 'd'
如何在不更改 index
或任何其他值(在本例中为 col2)的情况下对 col1
中的每个值进行排序?对于这个例子,如果我从最低到最高排序(假设字典排序与数字排序匹配)我会得到:
index col1 col2
1 ['1','2','3'] 'a'
2 ['2','2','4'] 'b'
3 ['1','2','5'] 'c'
4 ['1','2','3'] 'd'
我并不特别关心我采用哪种排序方法,我只是希望具有相同项目的列表具有相同的顺序,以便它们被认为是等效的,用于某些下游数据可视化。
谢谢!
提姆
【问题讨论】:
【参考方案1】:如果您不想使用任何导入(当然,pandas
除外):
import pandas as pd
df = pd.DataFrame('col1': [['1', '2', '20'], ['2', '10', '2'], ['30', '2', '1'], ['3', '2', '1']])
您可以使用以下方法对每个列表进行数字排序:
df[['col1']].apply(lambda x: sorted(map(int,x["col1"])), axis=1)
输出
0 [1, 2, 20]
1 [2, 2, 10]
2 [1, 2, 30]
3 [1, 2, 3]
或者作为字符串使用:
df[['col1']].apply(lambda x: sorted(map(str,x["col1"])), axis=1)
输出
0 [1, 2, 20]
1 [10, 2, 2]
2 [1, 2, 30]
3 [1, 2, 3]
【讨论】:
【参考方案2】:如果您想对整数的字符串表示形式进行排序,请使用natsort
:
from natsort import natsorted
df['col1'] = df['col1'].apply(natsorted)
输出:
index col1 col2
0 1 ['1', '2', '3'] 'a'
1 2 ['2', '2', '4'] 'b'
2 3 ['1', '2', '5'] 'c'
3 4 ['1', '2', '3'] 'd'
【讨论】:
【参考方案3】:如果col1
是字符串,则可以使用ast.literal_eval
将列转换为列表,然后使用apply
对其进行排序:
import ast
df.col1 = df.col1.apply(lambda x: sorted(ast.literal_eval(x)))
print(df)
输出:
col1 col2
index
1 [1, 2, 3] 'a'
2 [2, 2, 4] 'b'
3 [1, 2, 5] 'c'
4 [1, 2, 3] 'd'
【讨论】:
【参考方案4】:或者很好的旧列表理解。
df['col1'] = [sorted(i) for i in df.col1]
使用iris
的示例:
iris = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
iris['test'] = iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']].values.tolist()
iris['test2'] = [sorted(i) for i in iris.test]
【讨论】:
以上是关于pd.dataframe - 在不更改索引的情况下对列表列中的每个列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章