在Python中的日期范围内为每年创建新行?

Aub*_*rey 4 python range python-3.x pandas

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

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

桌子看起来像这样。

City    Color   Years
Paris     red       2010-2012
Rome      orange    2019-2020
New York  blue      2015-2018
Tokyo     purple    2002-2003
Run Code Online (Sandbox Code Playgroud)

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

City    Color   Years
Paris     red       2010
Paris     red       2011
...
New York  blue      2018
Tokyo     purple    2002
Tokyo     purple    2003
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 6

想法是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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)