Python与使用日期和条件的条件求和

Python与使用日期和条件的条件求和,python,pandas,date,sum,Python,Pandas,Date,Sum,我必须使用数据帧,我正在使用熊猫。 我想从一个可变日期和一列中的值进行累计和 我想在df2中添加第二列,显示日期,以了解df2中date2之后平均列的总和大于100的日期 例如,df1和df2是我开始使用的数据帧,df3是我想要的数据帧,df3['date100']是平均值之和大于100的日期: df1 = pd.DataFrame({'date1': ['1/1/2014', '2/1/2014', '3/1/2014','1/1/2014', '2/1/2014', '3/1/2014','

我必须使用数据帧,我正在使用熊猫。 我想从一个可变日期和一列中的值进行累计和

我想在df2中添加第二列,显示日期,以了解df2中date2之后平均列的总和大于100的日期

例如,df1和df2是我开始使用的数据帧,df3是我想要的数据帧,df3['date100']是平均值之和大于100的日期:

df1 = pd.DataFrame({'date1': ['1/1/2014', '2/1/2014', '3/1/2014','1/1/2014', '2/1/2014', '3/1/2014','1/1/2014', '2/1/2014', '3/1/2014'],
 'Place':['A','A','A','B','B','B','C','C','C'],'AVG': [62,14,47,25,74,60,78,27,41]})

df2 = pd.DataFrame({'date2': ['1/1/2014', '2/1/2014'], 'Place':['A','C'])})

*Something*
df3 = pd.DataFrame({'date2': ['1/1/2014', '2/1/2014'], 'Place':['A','C'], 'date100': ['3/1/2014', '2/1/2014'], 'sum': [123, 105]})

我找到了一些答案,但大多数都使用groupby,而df2没有分组。

由于您的示例非常基本,如果您有需要我处理的边缘案例,请询问。这一解决办法意味着:

解决方案:

#   For this solution your DataFrame needs to be sorted by date.
limit = 100
df = pd.DataFrame({
    'date1': ['1/1/2014', '2/1/2014', '3/1/2014','1/1/2014',
              '2/1/2014', '3/1/2014','1/1/2014', '2/1/2014', '3/1/2014'], 
    'Place':['A','A','A','B','B','B','C','C','C'],
    'AVG': [62,14,47,25,74,60,78,27,41]})

df2 = pd.DataFrame({'date2': ['1/1/2014', '2/1/2014'], 'Place':['A','C']})

result = []
for row in df2.to_dict('records'):
    #   For each date, I want to select the date that comes AFTER this one.
    #   Then, I take the .cumsum(), because it's the agg you wish to do.
    #   Filter by your limit and take the first occurrence.
    #   Converting this to a dict, appending it to a list, makes it easy
    #   to rebuild a DataFrame later.
    ndf = df.loc[ (df['date1'] >= row['date2']) & (df['Place'] == row['Place']) ]\
            .sort_values(by='date1')
    ndf['avgsum'] = ndf['AVG'].cumsum()
    final_df = ndf.loc[ ndf['avgsum'] >= limit ]

    #   Error handling, in case there is not avgsum above the threshold.
    try:
        final_df = final_df.iloc[0][['date1', 'avgsum']].rename({'date1' : 'date100'})
        result.append( final_df.to_dict() )
    except IndexError:
        continue

df3 = pd.DataFrame(result)

final_df = pd.concat([df2, df3], axis=1, sort=False)
print(final_df)
#       date2 Place  avgsum   date100
# 0  1/1/2014     A   123.0  3/1/2014
# 1  2/1/2014     C     NaN       NaN

由于您的示例非常基本,如果您有需要我处理的边缘案例,请询问。这一解决办法意味着:

解决方案:

#   For this solution your DataFrame needs to be sorted by date.
limit = 100
df = pd.DataFrame({
    'date1': ['1/1/2014', '2/1/2014', '3/1/2014','1/1/2014',
              '2/1/2014', '3/1/2014','1/1/2014', '2/1/2014', '3/1/2014'], 
    'Place':['A','A','A','B','B','B','C','C','C'],
    'AVG': [62,14,47,25,74,60,78,27,41]})

df2 = pd.DataFrame({'date2': ['1/1/2014', '2/1/2014'], 'Place':['A','C']})

result = []
for row in df2.to_dict('records'):
    #   For each date, I want to select the date that comes AFTER this one.
    #   Then, I take the .cumsum(), because it's the agg you wish to do.
    #   Filter by your limit and take the first occurrence.
    #   Converting this to a dict, appending it to a list, makes it easy
    #   to rebuild a DataFrame later.
    ndf = df.loc[ (df['date1'] >= row['date2']) & (df['Place'] == row['Place']) ]\
            .sort_values(by='date1')
    ndf['avgsum'] = ndf['AVG'].cumsum()
    final_df = ndf.loc[ ndf['avgsum'] >= limit ]

    #   Error handling, in case there is not avgsum above the threshold.
    try:
        final_df = final_df.iloc[0][['date1', 'avgsum']].rename({'date1' : 'date100'})
        result.append( final_df.to_dict() )
    except IndexError:
        continue

df3 = pd.DataFrame(result)

final_df = pd.concat([df2, df3], axis=1, sort=False)
print(final_df)
#       date2 Place  avgsum   date100
# 0  1/1/2014     A   123.0  3/1/2014
# 1  2/1/2014     C     NaN       NaN

以下是一个直接解决方案,假设如下:

  • df1
    按日期排序
  • df2
然后,您可以执行以下操作:

df2 = df2.join(pd.concat([
        pd.DataFrame(pd.DataFrame(df1.loc[df1.date1 >= d].AVG.cumsum()).query('AVG>=100')
                .iloc[0]).transpose()
        for d in df2.date2]).rename_axis('ix').reset_index())\
    .join(df1.drop(columns='AVG'), on='ix').rename(columns={'AVG': 'sum', 'date1': 'date100'})\
    .drop(columns='ix')[['date2', 'date100', 'sum']]
这样做的目的如下:

  • 对于df2中的每个日期,找到平均积数至少为100的第一个日期
  • 将结果合并到一个数据帧中,该数据帧由
    df1中该行的索引索引
  • 将该索引存储在
    ix
    列中,并重置该索引以将该数据帧连接到df2
  • 使用
    ix
    列将其连接到df1减去
    AVG
  • 重命名列,删除
    ix
    列,然后重新排序所有内容

    • 这里有一个直接的解决方案,假设如下:

      • df1
        按日期排序
      • df2
      然后,您可以执行以下操作:

      df2 = df2.join(pd.concat([
              pd.DataFrame(pd.DataFrame(df1.loc[df1.date1 >= d].AVG.cumsum()).query('AVG>=100')
                      .iloc[0]).transpose()
              for d in df2.date2]).rename_axis('ix').reset_index())\
          .join(df1.drop(columns='AVG'), on='ix').rename(columns={'AVG': 'sum', 'date1': 'date100'})\
          .drop(columns='ix')[['date2', 'date100', 'sum']]
      
      这样做的目的如下:

      • 对于df2中的每个日期,找到平均积数至少为100的第一个日期
      • 将结果合并到一个数据帧中,该数据帧由
        df1中该行的索引索引
      • 将该索引存储在
        ix
        列中,并重置该索引以将该数据帧连接到df2
      • 使用
        ix
        列将其连接到df1减去
        AVG
      • 重命名列,删除
        ix
        列,然后重新排序所有内容


      我不理解第一个df2与您想要执行的操作之间的关系。我对当天的列求和,因此对于df2[2/1/2014]中的第二个元素,我做了14+47+25+74。我不理解第一个df2与您想要执行的操作之间的关系。我对当天的列求和,因此对于df2中的第二个元素[2/1/2014]我做了14+47+25+74。谢谢它能工作,但我的数据没有分类。我还想知道是否有可能更进一步,因为事实上我有这样的东西:df=pd.DataFrame({'date1':['1/1/2014','2/2014','3/2/2014','4/2/2014','5/2/2014','AVG':[15,14,47,25,74],'Place:['A','A','B','C','A')和df2=pd.DataFrame:'['2014年1月1日','2014年1月2日','Place':['A','C'})。是否可以只计算列“位置”匹配的总和?是的,但我不在我的计算机前。我认为你应该事先问这个问题,因为现在你要问两个问题。当我在一个问题前时,我会尝试回答,但你应该能够使用简单的loc和你想要筛选的条件来完成。是的,我意识到了现在。我试图使用.loc,但我无法使其发挥作用。@yyzzz你应该编辑你的第一篇文章,并完成真正的最后一个问题。我还将我的数据放在我对Serge Ballesta的评论中(),谢谢它起作用,但我的数据没有排序。我还想知道是否有可能更进一步,因为实际上我有这样的东西:df=pd.DataFrame({'date1':[1/1/2014'、'2/1/2014'、'3/2/2014'、'4/2/2014'、'5/2/2014']、'AVG':[15,14,47,25,74]、'Place':[A'、'A'、'B'、'C'、'A')和df2=pd.DataFrame({'date2':[1/1/2014'、'2/1/2014']、'Place':[A'、'C'})。是否可以只计算列“位置”匹配的总和?是的,但我不在我的计算机前。我认为你应该事先问这个问题,因为现在你要问两个问题。当我在一个问题前时,我会尝试回答,但你应该能够使用简单的loc和你想要筛选的条件来完成。是的,我意识到了现在。我试图使用.loc,但我无法使其工作。@yyzz你应该编辑你的第一篇文章,并完成真正的最后一个问题。我还将我的数据放在我对Serge Ballesta的评论中()谢谢!我还想知道是否可以更进一步,因为实际上我有这样的东西:df=pd.DataFrame({'date1':[2014年1月1日”、“2014年2月1日”、“2014年3月2日”、“2014年4月2日”、“2014年5月2日”]、“平均值”:[15,14,47,25,74]、“地点”:[A'、'A'、'B'、'C'、'A')和df2=pd.DataFrame({'date2':[2014年1月1日]、'2014年2/1月']、'Place':[A'、'C'})。是否可以只对“地点”匹配的列求和?@yyzzz:在地点上添加条件不是问题。真正的问题是从
      df2
      开始的第二个日期没有解决方案,而这是我的一个假设。实际上,每个日期都有一个解决方案exist@yyzzz:你能给出一个输入数据的现实例子吗汉克斯!我还想知道是否有可能更进一步,因为实际上我有这样的东西:df=pd.DataFrame({'date1':['1/1/2014','2/1/2014','3/2/2014','4/2/2014','5/2/2014','AVG':[15,14,47,25,74],'Place':['A','A','B','C','A')和df2=pd.DataFrame({'date2':['1/1/2014','2/1/2014','Place A','C'))。是否可以只对“地点”匹配的列求和?@yyzzz:在地点上添加条件不是问题。真正的问题是从
      df2
      开始的第二个日期没有解决方案,而这是我的一个假设。实际上,每个日期都有一个解决方案exist@yyzzz:你能给出一个输入数据的现实例子吗?