【问题标题】:How to iteratively count in Pandas Dataframe如何在 Pandas Dataframe 中迭代计数
【发布时间】:2016-03-11 09:13:27
【问题描述】:

我想计算一个值在 pandas/python 中的当前位置出现的所有时间。必须考虑一个条件(数字必须出现在“分数”列中才能计算游戏已玩;如果我读取的 excel 文件中没有值,则显示为 NaN)。

下面的代码是我所在的位置:

import pandas as pd


df = pd.read_excel('G:\Project\SOQ1.xlsx')

df['date'] = pd.to_datetime(df['date'])

df = df.sort(columns='date')

df = df.set_index('date')

def calc_all_count(team_name):  
    home_count = df['home'].value_counts().get(team_name, 0)
    away_count = df['away'].value_counts().get(team_name, 0)
    all_count = home_count + away_count
    return all_count

def calc_home_count(team_name):    
    home_count = df['home'].value_counts().get(team_name, 0)
    return home_count

def calc_away_count(team_name):
    away_count = df['away'].value_counts().get(team_name, 0)
    return away_count

df['hag'] = df['home'].map(calc_all_count)
df['aag'] = df['away'].map(calc_all_count)
df['hahg'] = df['home'].map(calc_home_count)
df['aaag'] = df['away'].map(calc_away_count)

print df


                    league home away  hscore  ascore  hag  aag  hahg  aaag
date                                                                      
2015-01-03 03:02:00    MLB  Cle  Tex       9       6    3   15     2     7
2015-05-10 03:03:00    MLB  Bos  Cle       6       7   16    3     7     1
2015-10-15 03:00:00    MLB  Tex  Bos       5       2   15   16     8     9
2015-10-15 03:30:00    MLB  Tex  Bos       1       6   15   16     8     9
2015-10-16 00:00:00    MLB  Tex  Bos       4       4   15   16     8     9
2015-10-17 03:30:00    MLB  Bos  Tex       2       8   16   15     7     7
2015-10-18 00:00:00    MLB  Tex  Bos       9      10   15   16     8     9
2015-10-20 00:00:00    MLB  Bos  Tex       2       3   16   15     7     7
2015-10-21 00:00:00    MLB  Tex  Bos       5       1   15   16     8     9
2015-10-22 03:00:00    MLB  Tex  Bos       5       3   15   16     8     9
2015-10-23 00:00:00    MLB  Bos  Tex       3       4   16   15     7     7
2015-10-25 23:00:00    MLB  Bos  Tex       6       6   16   15     7     7
2015-10-25 23:00:00    MLB  Bos  Tex       5       1   16   15     7     7
2015-10-26 00:00:00    MLB  Tex  Bos       9       6   15   16     8     9
2015-10-27 01:30:00    MLB  Bos  Tex      10       5   16   15     7     7
2015-10-28 01:00:00    MLB  Tex  Bos     NaN     NaN   15   16     8     9
2015-11-20 03:01:00    MLB  Cle  Bos     NaN     NaN    3   16     2     9

我想要的是每场比赛之前的比赛次数。所以第一场比赛/行应该读为 0 的所有数字,因为没有人玩过。应该是这样的:

                    league home away  hscore  ascore  hag  aag  hahg  aaag
date                                                                      
2015-01-03 03:02:00    MLB  Cle  Tex       9       6    0    0     0     0
2015-05-10 03:03:00    MLB  Bos  Cle       6       7    0    1     0     0
2015-10-15 03:00:00    MLB  Tex  Bos       5       2    1    1     0     0
2015-10-15 03:30:00    MLB  Tex  Bos       1       6    2    2     1     1
2015-10-16 00:00:00    MLB  Tex  Bos       4       4    3    3     2     2
2015-10-17 03:30:00    MLB  Bos  Tex       2       8    4    4     1     1
2015-10-18 00:00:00    MLB  Tex  Bos       9      10    5    5     3     3
2015-10-20 00:00:00    MLB  Bos  Tex       2       3    6    6     2     2
2015-10-21 00:00:00    MLB  Tex  Bos       5       1    7    7     4     4
2015-10-22 03:00:00    MLB  Tex  Bos       5       3    8    8     5     5
2015-10-23 00:00:00    MLB  Bos  Tex       3       4    9    9     3     3
2015-10-25 23:00:00    MLB  Bos  Tex       6       6   10   10     4     4
2015-10-25 23:00:00    MLB  Bos  Tex       5       1   11   11     5     5
2015-10-26 00:00:00    MLB  Tex  Bos       9       6   12   12     6     6
2015-10-27 01:30:00    MLB  Bos  Tex      10       5   13   13     6     6
2015-10-28 01:00:00    MLB  Tex  Bos     NaN     NaN   14   14     7     7
2015-11-20 03:01:00    MLB  Cle  Bos     NaN     NaN    2   14     1     7

如何构建以计算“之前”当前位置?我想我应该使用 .iloc 或 .ix 但我想不通。

对实现此功能或更好的代码的任何帮助表示赞赏。也可以更好地提出问题的提示。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我的方法不使用map,而是使用stackgroupbypivot_tablemergecumsum函数:

    df.sort_values(by='date', axis=0, inplace = True)
    #set helper column for counting cumsum
    df['one'] = 1
    print df
    #                   date league home away  hscore  ascore  one
    #5   2015-01-03 03:02:00    MLB  Cle  Tex       9       6    1
    #0   2015-05-10 03:03:00    MLB  Bos  Cle       6       7    1
    #1   2015-10-15 03:00:00    MLB  Tex  Bos       5       2    1
    #2   2015-10-15 03:30:00    MLB  Tex  Bos       1       6    1
    #3   2015-10-16 00:00:00    MLB  Tex  Bos       4       4    1
    #4   2015-10-17 03:30:00    MLB  Bos  Tex       2       8    1
    #6   2015-10-18 00:00:00    MLB  Tex  Bos       9      10    1
    #7   2015-10-20 00:00:00    MLB  Bos  Tex       2       3    1
    #8   2015-10-21 00:00:00    MLB  Tex  Bos       5       1    1
    #9   2015-10-22 03:00:00    MLB  Tex  Bos       5       3    1
    #10  2015-10-23 00:00:00    MLB  Bos  Tex       3       4    1
    #11  2015-10-25 23:00:00    MLB  Bos  Tex       6       6    1
    #12  2015-10-25 23:00:00    MLB  Bos  Tex       5       1    1
    #13  2015-10-26 00:00:00    MLB  Tex  Bos       9       6    1
    #14  2015-10-27 01:30:00    MLB  Bos  Tex      10       5    1
    #15  2015-10-28 01:00:00    MLB  Tex  Bos     NaN     NaN    1
    #16  2015-11-20 03:01:00    MLB  Cle  Bos     NaN     NaN    1
    
    #set columns home and away to one columns for cumsum
    df2 = df[['date', 'home', 'away', 'one']].set_index(['date', 'one'])
    df2 = df2.stack().reset_index(name="both")
    df2['new'] =  df2.groupby(['both'])['one'].cumsum() - 1
    #print df2
    
    #get back to original index
    df1 = pd.pivot_table(df2, index=['date'], columns=['level_2'], values='new').reset_index()
    #print df1
    
    #merge with original df
    df1 = pd.merge(df, df1, on=['date'], suffixes=('', '_new'))
    
    #rename and casr float columns to integers columns
    df1 = df1.rename(columns={'away_new':'aag', 'home_new':'hag',})
    df1['aag'] = df1['aag'].astype(int)
    df1['hag'] = df1['hag'].astype(int)
    
    #count aaag and hahg
    df1['aaag'] =  df1.groupby(['away'])['one'].cumsum() - 1
    df1['hahg'] =  df1.groupby(['home'])['one'].cumsum() - 1
    
    #drop helper column one and set index
    df1 = df1.drop(['one'], axis=1 ).set_index('date')
    #reorder columns
    df1 = df1[['league', 'home', 'away', 'hscore', 'ascore', 'hag', 'aag', 'hahg', 'aaag']]
    
    print df1
                        league home away  hscore  ascore  hag  aag  hahg  aaag
    date                                                                      
    2015-01-03 03:02:00    MLB  Cle  Tex       9       6    0    0     0     0
    2015-05-10 03:03:00    MLB  Bos  Cle       6       7    0    1     0     0
    2015-10-15 03:00:00    MLB  Tex  Bos       5       2    1    1     0     0
    2015-10-15 03:30:00    MLB  Tex  Bos       1       6    2    2     1     1
    2015-10-16 00:00:00    MLB  Tex  Bos       4       4    3    3     2     2
    2015-10-17 03:30:00    MLB  Bos  Tex       2       8    4    4     1     1
    2015-10-18 00:00:00    MLB  Tex  Bos       9      10    5    5     3     3
    2015-10-20 00:00:00    MLB  Bos  Tex       2       3    6    6     2     2
    2015-10-21 00:00:00    MLB  Tex  Bos       5       1    7    7     4     4
    2015-10-22 03:00:00    MLB  Tex  Bos       5       3    8    8     5     5
    2015-10-23 00:00:00    MLB  Bos  Tex       3       4    9    9     3     3
    2015-10-25 23:00:00    MLB  Bos  Tex       6       6   10   10     4     4
    2015-10-25 23:00:00    MLB  Bos  Tex       5       1   10   10     5     5
    2015-10-26 00:00:00    MLB  Tex  Bos       9       6   12   12     6     6
    2015-10-27 01:30:00    MLB  Bos  Tex      10       5   13   13     6     6
    2015-10-28 01:00:00    MLB  Tex  Bos     NaN     NaN   14   14     7     7
    2015-11-20 03:01:00    MLB  Cle  Bos     NaN     NaN    2   15     1     8
    

    【讨论】:

    • 非常感谢您的回复@jezrael!我使用 df.sort(columns='date', axis=0, inplace=True) 而不是您的 df.sort_values 并且它有效。我理解代码,但一件事。您如何在 reset_index 上使用 name="both"?文档中没有提到
    • sort 已被删除 - link,所以我使用 df.sort_values。是的,name 不在文档中,我找到了它here
    • 其他选项是省略它然后重命名列 - df2 = df2.stack().reset_index() df2 = df2.rename(columns={0:'both'})
    • 你可以检查它,接受后你可以投票(因为你的代表将是 15)。然后你也可以投票。谢谢。
    • 我在reset_indexhere找到了name
    猜你喜欢
    • 2020-01-03
    • 2021-12-28
    • 2017-01-12
    • 1970-01-01
    • 2020-05-21
    • 2021-08-01
    • 2018-07-05
    • 2018-10-13
    • 2018-08-03
    相关资源
    最近更新 更多