Python 我对所有棒球运动员都有国家、开始和结束的年份。我需要知道每个国家每年有多少球员参加比赛

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 我

我有一个拥有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
我需要一张如下的桌子:

              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