我有一个拥有20,000名玩家的数据集。列为birthCountry,debut_year和final_year。
birthCountry debut_year final_year
0 USA 2004 2015
1 USA 1954 1976
2 USA 1962 1971
3 USA 1977 1990
4 USA 2001 2006
我需要获取如下表格:
1980 1981 1982
USA 50 49 48
CANADA XX XX XX
MEXICO XX XX XX
...
其中每个单元代表当年在特定国家/地区出生的球员数量。
我创建了一个嵌套列表,其中包含每个玩家玩过的所有年份。此列表的长度与df的长度相同。在df中,我每年创建一列,然后尝试为每个玩家/年份组合添加1。
想法是使用它来创建groupby或ivot_table
# create a list of years
years = list(range(min(df['debut_year'].values),max(df['final_year'].values)+1))
# create a list of countries
countries = df.birthCountry.unique()
# add columns for years
for n in range(1841,2019): #years are from 1841 to 2018
df[n] = ''
# now I have one additional column for every year. A lot of new empty columns
# temporary lists
templist = list(range(0,len(df)))
# every element of the following list contains all the years each player played
templist2 = []
for i in templist:
templist2.append(list(range(int(df.iloc[i,1]),int(df.iloc[i,2]))))
# add 1 if the player played that year
for i in range(len(df)):
for j in templist2[i]:
df.iloc[i][j] = 1
我跑了一段时间,然后在原始数据框中没有任何变化。
可能您会找到更好,更优雅的解决方案。
答案 0 :(得分:3)
为了限制示例的大小,我创建了以下源DataFrame:
df = pd.DataFrame(data=[[ 1, 'USA', 1974, 1978 ], [ 2, 'USA', 1976, 1981 ],
[ 3, 'USA', 1975, 1979 ], [ 4, 'USA', 1977, 1980 ],
[ 5, 'Mex', 1976, 1979 ], [ 6, 'Mex', 1978, 1980 ]],
columns=['Id', 'birthCountry', 'debut_year', 'final_year'])
实际计算的第一步是创建一个 Series 每个玩家活跃的年份:
years = df.apply(lambda row: pd.Series(range(row.debut_year,
row.final_year + 1)), axis=1).stack().astype(int).rename('year')
第二步是创建一个辅助DataFrame-连接
df.birthCountry
和years
:
df2 = df[['birthCountry']].join(years.reset_index(level=1, drop=True))
最后一步是产生实际结果:
df2.groupby(['birthCountry', 'year']).size().rename('Count')\
.unstack().fillna(0, downcast='infer')
对于以上测试数据,结果为:
year 1974 1975 1976 1977 1978 1979 1980 1981
birthCountry
Mex 0 0 1 1 2 2 1 0
USA 1 2 3 4 4 3 2 1
我认为,我的解决方案比之前提出的其他解决方案更具“泛音”感 由 Remy 。
答案 1 :(得分:1)
如果我正确理解您的df
变量的结构,便可以提出以下解决方案。我为示例创建了一个具有相同结构的字典列表(使用较小的年份范围):
df = [{'birthCountry': 'USA', 'debut_year': 2012, 'final_year': 2016},
{'birthCountry': 'CANADA', 'debut_year': 2010, 'final_year': 2016},
{'birthCountry': 'USA', 'debut_year': 2012, 'final_year': 2017},
{'birthCountry': 'CANADA', 'debut_year': 2012, 'final_year': 2017},
{'birthCountry': 'MEXICO', 'debut_year': 2012, 'final_year': 2016}]
countries = {}
for field in df:
if field['birthCountry'] not in countries.keys():
countries[field['birthCountry']] = {year: 0 for year in range(2010, 2019)}
for year in range(field['debut_year'], field['final_year']):
countries[field['birthCountry']][year] += 1