看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本例我们来看看如何通过构造一个 Series,并将这些返回的 Series 在 apply 中拼接为一个 DataFrame。本例是在一个列表形式的数据中,来解析开始和结束年份以及它们的最大年份间隔。
我们的源数据如下:
import pandas as pd
import io
data = '''
Years
[1990,1991,1995,2000,2001,2006]
[1990,1990]
[1980,1981,1990,1995]
'''
df = pd.read_csv(io.StringIO(data), sep=r'\s+')
df
# ...
这个数据只有一列 Years,它的值都是列表字符串,每个元素是一个年份。需求需要我们提取出这些年份的开始年份和结束年份,以及这些年份序列中只大的间隔(注意,不是开始和结束的间隔)。
得到的数据如下:
'''
from_year to_year largest_gap
0 1990 2006 5
1 1990 1990 0
2 1980 1995 9
'''
我们可以先将每行的字符串用 eval() 转为 Python 对象,它是一个列表,每个元素是一个整型。
接着,编写一个函数,传入每行的列表,每行返回一个 Series,这些 Series 会组成我们最终的 DataFrame。
我们再来分析下这函数的逻辑,将列表传入 pd.Series
中,形成一个 Series,方便我们利用 Series 的丰富功能进行操作。
Series 的最小值和最大值就是开始和结束年份,用 diff() 求出一个前后差的序列,然后取这个差的序列的最大值就是最大的间隔年份。
先将 Series 转为一个列表:
(
df.Years
.map(eval)
)
'''
0 [1990, 1991, 1995, 2000, 2001, 2006]
1 [1990, 1990]
2 [1980, 1981, 1990, 1995]
Name: Years, dtype: object
'''
每行是一个列表,接着我们按照思路来编辑处理函数:
def func(years: list) -> pd.Series:
ser = pd.Series(years)
index = ['from_year', 'to_year', 'largest_gap']
data = [ser.min(),
ser.max(),
ser.diff().abs().max()]
return pd.Series(data, index=index, dtype=int)
最后来调用这个函数:
(
df.Years
.map(eval)
.apply(func)
)
'''
from_year to_year largest_gap
0 1990 2006 5
1 1990 1990 0
2 1980 1995 9
'''
还可以将年份转为周期进行计算:
(
df.Years.map(eval)
.explode()
.map(pd.Period)
.groupby(level=0)
.agg(from_year='min',
to_year='max',
largest_gap=lambda x: x.diff().dropna().map(lambda x: x.n).max()
)
)
这样就得到了最终的结果。
(完)
更新时间:2024-08-18 16:18:13 标签:pandas python 年份