python pandas排序问题

发布于 2022-09-12 01:06:56 字数 268 浏览 17 评论 0

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

微信截图_20200119121843.png

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

微信截图_20200116124609.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

み零 2022-09-19 01:06:56
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

结果.png

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

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

排序.png

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

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

这个列表。

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

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
寄人书 2022-09-19 01:06:56

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

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 相关函数替代,否则数据量大的时候会非常慢,能差几个数量级?

路弥 2022-09-19 01:06:56

利用一下楼上数据

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])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文