Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python反聚合_Python_Pandas - Fatal编程技术网

Python反聚合

Python反聚合,python,pandas,Python,Pandas,我有一个在两个日期之间聚合的数据集,我想通过将总数除以这些日期之间的天数来每天对其进行反聚合。 作为样本 StoreID Date_Start Date_End Total_Number_of_sales 78 12/04/2015 17/05/2015 79089 80 12/04/2015 17/05/2015 79089 我想要的数据集是: StoreID Date Number_Sales 78

我有一个在两个日期之间聚合的数据集,我想通过将总数除以这些日期之间的天数来每天对其进行反聚合。 作为样本

StoreID Date_Start    Date_End     Total_Number_of_sales
78       12/04/2015    17/05/2015    79089
80       12/04/2015    17/05/2015    79089
我想要的数据集是:

StoreID Date         Number_Sales 
78         12/04/2015    79089/38(as there are 38 days in between)
78         13/04/2015    79089/38(as there are 38 days in between) 
78         14/04/2015    79089/38(as there are 38 days in between)
78         ...
78         17/05/2015    79089/38(as there are 38 days in between)
任何帮助都是有用的。
谢谢

我不确定这是否正是您想要的,但您可以试试这个(我添加了另一个虚拟行):


首先将字符串日期转换为datetime对象(以便可以计算两个范围之间的天数),然后根据日期范围创建一个新索引,并划分销售额。循环将数据帧的每一行粘贴到一个“扩展”数据帧中,然后将它们连接到一个主数据帧中。

创建一个新的数据帧怎么样

start = pd.to_datetime(df['Date_Start'].values[0], dayfirst=True)
end = pd.to_datetime(df['Date_End'].values[0], dayfirst=True)
idx = pd.DatetimeIndex(start=start, end=end, freq='D')
res = pd.DataFrame(df['Total_Number_of_sales'].values[0]/len(idx), index=idx, columns=['Number_Sales'])
屈服

In[42]: res.head(5)
Out[42]: 
            Number_Sales
2015-04-12   2196.916667
2015-04-13   2196.916667
2015-04-14   2196.916667
2015-04-15   2196.916667
2015-04-16   2196.916667
如果您有多个存储(根据您的评论和编辑),那么您可以在所有行上循环,计算销售额,然后连接生成的数据帧

df = pd.DataFrame({'Store_ID': [78, 78, 80],
    'Date_Start': ['12/04/2015', '18/05/2015', '21/06/2015'],
                   'Date_End': ['17/05/2015', '10/06/2015', '01/07/2015'],
                   'Total_Number_of_sales': [79089., 50000., 25000.]})

to_concat = []
for _, row in df.iterrows():
    start = pd.to_datetime(row['Date_Start'], dayfirst=True)
    end = pd.to_datetime(row['Date_End'], dayfirst=True)
    idx = pd.DatetimeIndex(start=start, end=end, freq='D')
    sales = [row['Total_Number_of_sales']/len(idx)] * len(idx)
    id = [row['Store_ID']] * len(idx)
    res = pd.DataFrame({'Store_ID': id, 'Number_Sales':sales}, index=idx)
    to_concat.append(res)

res = pd.concat(to_concat)

当然还有更优雅的解决方案,看看这个例子。

考虑用
DataFrame
构造函数遍历每一行主数据帧来构建一个数据帧列表。每一次迭代都将从开始日期到范围结束的一系列天数展开,总销售额的所需销售部门按天数的差异进行划分:

from io import StringIO
import pandas as pd
from datetime import timedelta

txt = '''StoreID Date_Start    Date_End     Total_Number_of_sales
78       12/04/2015    17/05/2015    79089
80       12/04/2015    17/05/2015    89089'''

df = pd.read_table(StringIO(txt), sep="\s+", parse_dates=[1, 2], dayfirst=True)
df['Diff_Days'] = (df['Date_End'] - df['Date_Start']).dt.days

def calc_days_sales(row): 
    long_df = pd.DataFrame({'StoreID': row['StoreID'],
                            'Date': [row['Date_Start'] + timedelta(days=i) 
                                          for i in range(row['Diff_Days']+1)],
                            'Number_Sales': row['Total_Number_of_sales'] / row['Diff_Days']})    
    return long_df

df_list = [calc_days_sales(row) for i, row in df.iterrows()]

final_df = pd.concat(df_list).reindex(['StoreID', 'Date', 'Number_Sales'], axis='columns')

print(final_df.head(10))
#    StoreID       Date  Number_Sales
# 0       78 2015-04-12   2259.685714
# 1       78 2015-04-13   2259.685714
# 2       78 2015-04-14   2259.685714
# 3       78 2015-04-15   2259.685714
# 4       78 2015-04-16   2259.685714
# 5       78 2015-04-17   2259.685714
# 6       78 2015-04-18   2259.685714
# 7       78 2015-04-19   2259.685714
# 8       78 2015-04-20   2259.685714
# 9       78 2015-04-21   2259.685714

Python 3.6不需要在末尾重新编制索引,因为数据帧的输入字典将被订购。

谢谢您的回答,问题是我想对所有存储ID执行此操作,因此它需要循环所有存储,有什么想法吗?所有存储的开始和结束日期是否相同?没有,它们不同。同一个商店可以有不同的开始和结束日期,因为它们是一段时间内的聚合值,在较长的时间内,商店有多行。谢谢你的回答,问题是我想对所有商店ID执行此操作,所以它需要循环所有商店,所以最终df也应该包括它们,有什么想法吗?
from io import StringIO
import pandas as pd
from datetime import timedelta

txt = '''StoreID Date_Start    Date_End     Total_Number_of_sales
78       12/04/2015    17/05/2015    79089
80       12/04/2015    17/05/2015    89089'''

df = pd.read_table(StringIO(txt), sep="\s+", parse_dates=[1, 2], dayfirst=True)
df['Diff_Days'] = (df['Date_End'] - df['Date_Start']).dt.days

def calc_days_sales(row): 
    long_df = pd.DataFrame({'StoreID': row['StoreID'],
                            'Date': [row['Date_Start'] + timedelta(days=i) 
                                          for i in range(row['Diff_Days']+1)],
                            'Number_Sales': row['Total_Number_of_sales'] / row['Diff_Days']})    
    return long_df

df_list = [calc_days_sales(row) for i, row in df.iterrows()]

final_df = pd.concat(df_list).reindex(['StoreID', 'Date', 'Number_Sales'], axis='columns')

print(final_df.head(10))
#    StoreID       Date  Number_Sales
# 0       78 2015-04-12   2259.685714
# 1       78 2015-04-13   2259.685714
# 2       78 2015-04-14   2259.685714
# 3       78 2015-04-15   2259.685714
# 4       78 2015-04-16   2259.685714
# 5       78 2015-04-17   2259.685714
# 6       78 2015-04-18   2259.685714
# 7       78 2015-04-19   2259.685714
# 8       78 2015-04-20   2259.685714
# 9       78 2015-04-21   2259.685714