python pandas排序问题

原始数据的excel表格,如下图

python pandas排序问题

想用python的pandas把excel变成按相同地点和按相同地点的数量由大到小排序,如下图

python pandas排序问题


回答:

In [48]: import pandas as pd

...:

...: # 读取文件

...: df = pd.read_excel('data.xlsx')

...:

...: # 按照city进行分组,并按照date升序排序

...: new_df = df.sort_values(['date']).groupby('city')

...:

...: # 取出结果中的每一行拼接成新的dataframe

...: data_list = [pd.DataFrame(row) for head, row in new_df]

...: res_df = pd.concat(data_list)

...: res_df

python pandas排序问题

如果需要自定义city的顺序,可以使用pd.Categorical修改city的顺序。

res_df["city"] = pd.Categorical(df["city"],["广州","南京","杭州","北京","上海"])

res = res_df.sort_values("city")

res

python pandas排序问题

如果要自动生成特定的自定义城市顺序,只需要通过程序生成

["广州","南京","杭州","北京","上海"]

这个列表。

这个程序的生成逻辑是:原始表的城市名去倒序排列,后保持顺序去重。

In [9]: df['city'].values.tolist()[::-1]

Out[9]: ['广州', '广州','广州', '广州', '南京', '南京', '南京', '南京', '杭州', '杭州', '杭州', '北京', '北京', '广州', '上海']

直接set去重会破坏顺序,需要自定义一个函数

def remove_duplicate(items):

seen = set()

for item in items:

if item not in seen:

yield item

seen.add(item)

return list(seen)

因此,最后列表生成的方法为:

city_order = remove_duplicate(df['city'].values.tolist()[::-1])

最终代码:

import pandas as pd

df = pd.read_excel('data.xlsx')

new_df = df.sort_values(['date']).groupby('city')

data_list = [pd.DataFrame(row) for head, row in new_df]

res_df = pd.concat(data_list)

def remove_duplicate(items):

seen = set()

for item in items:

if item not in seen:

yield item

seen.add(item)

return list(seen)

city_order = remove_duplicate(df['city'].values.tolist()[::-1])

res_df["city"] = pd.Categorical(df["city"],city_order)

# 重排后顺序会乱,再增加date修正

res = res_df.sort_values(["city","date"])

res

最后结果:

   city       date

2 广州 2020-01-17

4 广州 2020-01-19

5 广州 2020-01-20

6 广州 2020-01-21

14 广州 2020-01-29

1 南京 2020-01-16

11 南京 2020-01-26

12 南京 2020-01-27

13 南京 2020-01-28

8 杭州 2020-01-23

9 杭州 2020-01-24

10 杭州 2020-01-25

3 北京 2020-01-18

7 北京 2020-01-22

0 上海 2020-01-15

修改原始数据后,最终的结果如下

   city       date

5 广宁 2020-01-20

6 广宁 2020-01-21

2 广州 2020-01-17

4 广州 2020-01-19

12 广州 2020-01-27

13 广州 2020-01-28

14 广州 2020-01-29

1 南京 2020-01-16

11 南京 2020-01-26

15 南京 2020-01-30

16 南京 2020-01-31

8 杭州 2020-01-23

9 杭州 2020-01-24

10 杭州 2020-01-25

3 北京 2020-01-18

7 北京 2020-01-22

0 上海 2020-01-15

根据城市的出现的个数倒序进行排列的代码如下:

import pandas as pd

df = pd.read_excel('data.xlsx')

new_df = df.sort_values(['date']).groupby('city')

data_list = [pd.DataFrame(row) for head, row in new_df]

res_df = pd.concat(data_list)

from collections import Counter

city_counter = Counter(df['city'].values.tolist())

city_order = [k for k, v in sorted(city_counter.items(), key=lambda item:item[1], reverse=True)]

res_df["city"] = pd.Categorical(df["city"],city_order)

# 重排后顺序会乱,再增加date修正

res = res_df.sort_values(["city","date"])

res

结果如下:

   city       date

2 广州 2020-01-17

4 广州 2020-01-19

12 广州 2020-01-27

13 广州 2020-01-28

14 广州 2020-01-29

1 南京 2020-01-16

11 南京 2020-01-26

15 南京 2020-01-30

16 南京 2020-01-31

8 杭州 2020-01-23

9 杭州 2020-01-24

10 杭州 2020-01-25

3 北京 2020-01-18

7 北京 2020-01-22

5 广宁 2020-01-20

6 广宁 2020-01-21

0 上海 2020-01-15


回答:

逻辑上没那么复杂,添加个计数辅助列,然后多列排序完事:

import pandas as pd  

from io import StringIO

data = """

city,date

上海,2020/1/15

南京,2020/1/16

广州,2020/1/17

北京,2020/1/18

广州,2020/1/19

广宁,2020/1/20

广宁,2020/1/21

北京,2020/1/22

杭州,2020/1/23

杭州,2020/1/24

杭州,2020/1/25

南京,2020/1/26

广州,2020/1/27

广州,2020/1/28

广州,2020/1/29

南京,2020/1/30

南京,2020/1/31

"""

df = pd.read_csv(StringIO(data))

df = df.merge(

df.groupby("city", as_index=False).count().rename(columns={"date": "count"}),

how="left",

on="city",

).sort_values(by=["count", "city", "date"], ascending=[0, 0, 1])

print(df)

执行结果:

   city       date  count

2 广州 2020/1/17 5

4 广州 2020/1/19 5

12 广州 2020/1/27 5

13 广州 2020/1/28 5

14 广州 2020/1/29 5

1 南京 2020/1/16 4

11 南京 2020/1/26 4

15 南京 2020/1/30 4

16 南京 2020/1/31 4

8 杭州 2020/1/23 3

9 杭州 2020/1/24 3

10 杭州 2020/1/25 3

3 北京 2020/1/18 2

5 广宁 2020/1/20 2

6 广宁 2020/1/21 2

7 北京 2020/1/22 2

0 上海 2020/1/15 1

注意,既然使用了 Pandas 就尽量不要使用 Python 原生列表类操作,用 pandas/numpy 相关函数替代,否则数据量大的时候会非常慢,能差几个数量级?


回答:

利用一下楼上数据

import pandas as pd  

from io import StringIO

data = """

city,date

上海,2020/1/15

南京,2020/1/16

广州,2020/1/17

北京,2020/1/18

广州,2020/1/19

广宁,2020/1/20

广宁,2020/1/21

北京,2020/1/22

杭州,2020/1/23

杭州,2020/1/24

杭州,2020/1/25

南京,2020/1/26

广州,2020/1/27

广州,2020/1/28

广州,2020/1/29

南京,2020/1/30

南京,2020/1/31

"""

a = pd.read_csv(StringIO(data))

a['b'] = a.city.apply(lambda x:a.city.value_counts()[x])

a.sort_values(by=['b','date'],ascending=[False,False])

以上是 python pandas排序问题 的全部内容, 来源链接: utcz.com/a/164952.html

回到顶部