首页 > 解决方案 > 在 Python 的日期范围内为每年创建新行?

问题描述

我有一个数据框,其中每一行都有一系列年份。这是构建它的代码。

original = pd.DataFrame({'City': ['Paris','Rome','New York', 'Tokyo'], 'Color': ['red', 'orange', 'blue', 'purple'], 'Years': ['2010-2012', '2019-2020', '2015-2018', '2002-2003']})

桌子看起来像这样。

City    Color   Years
Paris     red       2010-2012
Rome      orange    2019-2020
New York  blue      2015-2018
Tokyo     purple    2002-2003

我想在“年份”范围内为每一年创建一个新行。数据框应如下所示。

City    Color   Years
Paris     red       2010
Paris     red       2011
...
New York  blue      2018
Tokyo     purple    2002
Tokyo     purple    2003

这是我现在正在使用的代码。我试图为每年添加一个新行,但它只返回一个空数据框,我不知道为什么。

df_empty = pd.DataFrame({'City': [], 'Color': [], 'Years': []})

for index, row in original.iterrows():
    dates = [int(s) for s in row['Years'].split("-") if s.isdigit()]
    for i in range(dates[0],dates[1] + 1):
        newrow = row
        newrow.append(pd.Series([str(i)]))
        df_empty.add(newrow)

标签: pythonpython-3.xpandasrange

解决方案


想法是Series.str.splitnew 的列DataFrame,因此可能会按年份的差异重复索引值。也用于GroupBy.cumcount添加每个索引值的所有年份范围:

df = original['Years'].str.split('-', expand=True).astype(int)
original['Years'] = df[0]
df = original.loc[original.index.repeat(df[1] - df[0] + 1)]
df['Years'] += df.groupby(level=0).cumcount()
df = df.reset_index(drop=True)
print (df)
        City   Color  Years
0      Paris     red   2010
1      Paris     red   2011
2      Paris     red   2012
3       Rome  orange   2019
4       Rome  orange   2020
5   New York    blue   2015
6   New York    blue   2016
7   New York    blue   2017
8   New York    blue   2018
9      Tokyo  purple   2002
10     Tokyo  purple   2003

DataFrame.explode多年来对范围第一个4和最后一个4字符进行列表理解的另一种解决方案:

original['Years'] = [[y for y in range(int(x[:4]), int(x[-4:]) + 1)] 
                        for x in original['Years']]

original = original.explode('Years').reset_index(drop=True)
print (original)
        City   Color Years
0      Paris     red  2010
1      Paris     red  2011
2      Paris     red  2012
3       Rome  orange  2019
4       Rome  orange  2020
5   New York    blue  2015
6   New York    blue  2016
7   New York    blue  2017
8   New York    blue  2018
9      Tokyo  purple  2002
10     Tokyo  purple  2003

推荐阅读