Python 我对所有棒球运动员都有国家、开始和结束的年份。我需要知道每个国家每年有多少球员参加比赛
我有一个拥有20000名玩家的数据集。栏目包括出生国、首次亮相年和最后一年Python 我对所有棒球运动员都有国家、开始和结束的年份。我需要知道每个国家每年有多少球员参加比赛,python,pandas,Python,Pandas,我有一个拥有20000名玩家的数据集。栏目包括出生国、首次亮相年和最后一年 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 我
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或pivot_表
创建年份列表
年份=listrangemindf[“首次登场年份]。值,maxdf[“最终年份]。值+1
创建一个国家列表
国家=df.birthCountry.unique
添加年列
对于范围为18412019的n:年份从1841年到2018年
df[n]=
现在我每年增加一个专栏。许多新的空列
临时名单
templist=listrange0,lendf
下面列表中的每个元素都包含每个玩家玩过的所有年份
templist2=[]
对于我在圣殿骑士团:
templist2.appendlistrangeintdf.iloc[i,1],intdf.iloc[i,2]
如果球员当年参加比赛,则添加1
对于rangelendf中的i:
对于templist2[i]中的j:
df.iloc[i][j]=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
如果我正确理解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
为了限制示例的大小,我创建了以下源数据帧:
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'])
实际计算的第一步是创建一个包含
每位玩家活跃的年份:
years = df.apply(lambda row: pd.Series(range(row.debut_year,
row.final_year + 1)), axis=1).stack().astype(int).rename('year')
第二步是创建一个辅助数据帧-一个
df.出生国和年份:
最后一步是产生实际结果:
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
我认为,我的解决方案比之前提出的另一个更具泛达索式
为了限制示例的大小,我创建了以下源数据帧:
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'])
实际计算的第一步是创建一个包含
每位玩家活跃的年份:
years = df.apply(lambda row: pd.Series(range(row.debut_year,
row.final_year + 1)), axis=1).stack().astype(int).rename('year')
第二步是创建一个辅助数据帧-一个
df.出生国和年份:
最后一步是产生实际结果:
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编写。谢谢Remy,您的解决方案只使用了几行代码。Valdi_-Bo的解决方案给了我一个很好的格式表,这就是为什么我选择他的答案作为被接受的答案。无论如何感谢@RemyThanks Remy,您的解决方案只使用了几行代码。Valdi_-Bo的解决方案给了我一个很好的格式表,这就是为什么我选择他的答案作为被接受的答案。无论如何谢谢你@Remy