【问题标题】:Calculate mean of data rows in dataframe with date-headers, dictated by a 'datetime'-column使用日期标题计算数据帧中数据行的平均值,由“日期时间”列指示
【发布时间】:2020-08-22 00:29:58
【问题描述】:

我有一个包含客户 ID 及其 2014-2018 年费用的数据框。我想要的是获得每个 ID 费用的平均值,但在计算平均值时只能考虑某个日期之前的年份(因此“日期”列指示可以将哪些列考虑在内)。

示例:对于索引 0(ID:12),日期状态为“2016-03-08”,则平均值应取自列“y_2014”和“y_2015”,因此对于该索引,平均值是 111.0。 如果日期太早(例如,在这种情况下为 2014 年或更早),则应返回 NaN(参见索引 6 和 9)。

初始数据框:

   y_2014  y_2015  y_2016  y_2017  y_2018        Date  ID  
0   100.0   122.0     324     632     NaN  2016-03-08  12   
1   120.0   159.0      54     452   541.0  2015-04-09  96   
2     NaN   164.0     687     165   245.0  2016-02-15  20   
3   180.0   421.0     512     184   953.0  2018-05-01  73  
4   110.0   654.0     913     173   103.0  2017-08-04  84   
5   130.0     NaN     754     124   207.0  2016-07-03  26   
6   170.0   256.0     843      97   806.0  2013-02-04  87    
7   140.0   754.0      95     101   541.0  2016-06-08  64    
8    80.0   985.0     184      84    90.0  2019-03-05  11  
9    96.0    65.0     127     130   421.0  2014-05-14  34     

期望的输出:

   y_2014  y_2015  y_2016  y_2017  y_2018        Date  ID    mean
0   100.0   122.0     324     632     NaN  2016-03-08  12   111.0
1   120.0   159.0      54     452   541.0  2015-04-09  96   120.0
2     NaN   164.0     687     165   245.0  2016-02-15  20   164.0
3   180.0   421.0     512     184   953.0  2018-05-01  73  324.25
4   110.0   654.0     913     173   103.0  2017-08-04  84   559.0
5   130.0     NaN     754     124   207.0  2016-07-03  26   130.0
6   170.0   256.0     843      97   806.0  2013-02-04  87     NaN
7   140.0   754.0      95     101   541.0  2016-06-08  64     447
8    80.0   985.0     184      84    90.0  2019-03-05  11   284.6
9    96.0    65.0     127     130   421.0  2014-05-14  34     NaN

尝试过的代码: -> 我仍在努力,因为我真的不知道如何开始,我到目前为止只上传了数据帧,可能是“日期时间” '-package 必须完成才能获得所需的数据帧?

import pandas as pd

import numpy as np

import datetime

df = pd.DataFrame({"ID":   [12,96,20,73,84,26,87,64,11,34],
 
                 "y_2014": [100,120,np.nan,180,110,130,170,140,80,96],
   
                 "y_2015": [122,159,164,421,654,np.nan,256,754,985,65],
     
                 "y_2016": [324,54,687,512,913,754,843,95,184,127],
   
                 "y_2017": [632,452,165,184,173,124,97,101,84,130],
   
                 "y_2018": [np.nan,541,245,953,103,207,806,541,90,421],
 
                 "Date": ['2016-03-08', '2015-04-09', '2016-02-15', '2018-05-01', '2017-08-04',
                          
                          '2016-07-03', '2013-02-04', '2016-06-08', '2019-03-05', '2014-05-14']})

print(df)

【问题讨论】:

  • 这些数据从何而来? 可能需要使用 'datetime'-package 进行某些操作才能获得所需的数据帧? Pandas 包含处理日期和时间的功能。
  • 这只是一些测试操作的示例数据,我不能分享实际的数据集 ;-) 好的,我会进一步研究。
  • 好的,我会进一步研究。请这样做,并在出现特定问题时报告。
  • 哇,你肯定在这里提供了最有帮助的 cmets。这个论坛对各种与代码相关的问题都是开放的。这是一个我真正付出努力的问题,定义了问题,提供了一个例子,如果我知道答案,我不会问,所以如果这是你能说的最好的,我会很;)非常感谢。
  • 哇,你肯定给了这里最有帮助的 cmets.. 你无权获得答案。 如果我知道答案,我不会问 恕我直言,我不确定我是否理解这与我的评论有什么关系,这绝不是粗鲁或煽动性的。 这个论坛对各种与代码相关的问题都是开放的。 这不是典型意义上的论坛,仍然需要遵循规则和约定。 所以,如果这是你能说的最好的话,我会非常感谢 ;) 非常感谢。 同样,你无权获得答案,也无权免于其他一切。

标签: python pandas datetime mean


【解决方案1】:

由于您的命名约定,需要从列名中提取年份以进行比较。然后你可以屏蔽数据并取平均值:

# the years from columns
data = df.filter(like='y_')
data_years = data.columns.str.extract('(\d+)')[0].astype(int)

# the years from Date
years = pd.to_datetime(df.Date).dt.year.values

df['mean'] = data.where(data_years<years[:,None]).mean(1)

输出:

   y_2014  y_2015  y_2016  y_2017  y_2018       Date  ID    mean
0   100.0   122.0     324     632     NaN 2016-03-08  12  111.00
1   120.0   159.0      54     452   541.0 2015-04-09  96  120.00
2     NaN   164.0     687     165   245.0 2016-02-15  20  164.00
3   180.0   421.0     512     184   953.0 2018-05-01  73  324.25
4   110.0   654.0     913     173   103.0 2017-08-04  84  559.00
5   130.0     NaN     754     124   207.0 2016-07-03  26  130.00
6   170.0   256.0     843      97   806.0 2013-02-04  87     NaN
7   140.0   754.0      95     101   541.0 2016-06-08  64  447.00
8    80.0   985.0     184      84    90.0 2019-03-05  11  284.60
9    96.0    65.0     127     130   421.0 2014-05-14  34     NaN

【讨论】:

  • 运行时出现以下错误:AttributeError: Can only use .str accessor with string values (i.e. inferred_type is 'string', 'unicode' or 'mixed')
  • 那行代码是从y_2014 y_2015 y_2016 y_2017 y_2018中提取2014, 2015, 2016, 2017, 2018的值。我不确定您的实际数据列名称是什么。
  • 实际数据列是相似的,一个包含 2014、2015、2016、2017、2018 的字符串,这就是我这样定义它们的原因;)所以确实从标题中提取年份似乎很好开始,但是是什么导致了错误呢?
【解决方案2】:

还有一个答案:

import pandas as pd

import numpy as np



df = pd.DataFrame({"ID":   [12,96,20,73,84,26,87,64,11,34],
                 
               "y_2014": [100,120,np.nan,180,110,130,170,140,80,96],
   
               "y_2015": [122,159,164,421,654,np.nan,256,754,985,65],
                 
               "y_2016": [324,54,687,512,913,754,843,95,184,127],
  
               "y_2017": [632,452,165,184,173,124,97,101,84,130],
                 
               "y_2018": [np.nan,541,245,953,103,207,806,541,90,421],
  
                 "Date": ['2016-03-08', '2015-04-09', '2016-02-15', '2018-05-01', '2017-08-04',
               
                          '2016-07-03', '2013-02-04', '2016-06-08', '2019-03-05', '2014-05-14']})

#Subset from original df to calculate mean
subset = df.loc[:,['y_2014', 'y_2015', 'y_2016', 'y_2017', 'y_2018']]


#an expense value is only available for the calculation of the mean when that year has passed, therefore 2015-01-01 is chosen for the 'y_2014' column in the subset etc. to check with the 'Date'-column
subset.columns = ['2015-01-01', '2016-01-01', '2017-01-01', '2018-01-01', '2019-01-01']


s = subset.columns[0:].values < df.Date.values[:,None]

t = s.astype(float)
t[t == 0] = np.nan


df['mean'] = (subset.iloc[:,0:]*t).mean(1)


print(df)

#Additionally: (gives the sum of expenses before a certain date in the 'Date'-column
df['sum'] = (subset.iloc[:,0:]*t).sum(1)


print(df)


【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2020-07-04
    • 2018-10-25
    • 1970-01-01
    • 2019-07-12
    • 2017-12-02
    • 1970-01-01
    • 2010-10-30
    相关资源
    最近更新 更多