繁体   English   中英

熊猫数据框根据日期划分行

[英]Pandas dataframe divide rows based on dates

我每天都有一列值,而每周有另一列值。 我想将每天的价值除以对应的公司和集团所在的一周的每周价值。 我正在尝试找出一种无循环的方法,我觉得有一种方法可以在pandas或numpy中进行,但我无法弄清楚。 谢谢您的帮助!

例如,我有两个数据框:

df1 =

Company Group Date       People
A       X     01/07/2015 5
A       X     01/14/2015 10
A       XX    01/07/2015 6
A       XX    01/14/2015 12
B       Y     01/07/2015 4
B       Y     01/14/2015 8
B       YY    01/07/2015 5
B       YY    01/14/2015 4

df2 =

Company Group Date       Value
A       X     01/04/2015 5
A       X     01/06/2015 10
A       X     01/13/2015 15
A       XX    01/05/2015 6
A       XX    01/06/2015 9
A       XX    01/11/2015 9
A       XX    01/14/2015 12
B       Y     01/05/2015 4
B       Y     01/07/2015 6
B       Y     01/13/2015 16
B       Y     01/14/2015 24
B       YY    01/03/2015 10
B       YY    01/11/2015 10
B       YY    01/14/2015 12

我希望结果是:

Company Group Date       Value/People
A       X     01/04/2015 1
A       X     01/06/2015 2
A       X     01/13/2015 1.5
A       XX    01/05/2015 1
A       XX    01/06/2015 1.5
A       XX    01/11/2015 0.75
A       XX    01/14/2015 1
B       Y     01/05/2015 1
B       Y     01/07/2015 1.5
B       Y     01/13/2015 2
B       Y     01/14/2015 3
B       YY    01/03/2015 2
B       YY    01/11/2015 2.5
B       YY    01/14/2015 3

存储在DataFrames和Series中的类似日期的值的基础dtype是NumPy datetime64[ns] 可以通过调用astype('datetime64[?]')datetime64[ns]值数组“裁剪”为标准的秒,分钟,小时,天,周,月或年,其中? 用适当的单位(例如smhDWMY )代替。

在这里,如果我们可以将每个日期分类为标准的一周,则将在很大程度上解决我们的问题。 我们可以使用.astype('datetime64[W]')来做到这一点:

In [152]: df1['Week'] = df1['Date'].values.astype('datetime64[W]'); df1
Out[152]: 
  Company       Date Group  People       Week
0       A 2015-01-07     X       5 2015-01-01
1       A 2015-01-14     X      10 2015-01-08
2       A 2015-01-07    XX       6 2015-01-01
3       A 2015-01-14    XX      12 2015-01-08
4       B 2015-01-07     Y       4 2015-01-01
5       B 2015-01-14     Y       8 2015-01-08
6       B 2015-01-07    YY       5 2015-01-01
7       B 2015-01-14    YY       4 2015-01-08

完成df1df2 ,我们现在可以在['Week', 'Group', 'Company']上合并DataFrame。 这将匹配df1和df2中的相应行。 这样就很容易找到价值与人的比例。


import pandas as pd
df1 = pd.DataFrame({'Company': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'], 'Date': ['01/07/2015', '01/14/2015', '01/07/2015', '01/14/2015', '01/07/2015', '01/14/2015', '01/07/2015', '01/14/2015'], 'Group': ['X', 'X', 'XX', 'XX', 'Y', 'Y', 'YY', 'YY'], 'People': [5, 10, 6, 12, 4, 8, 5, 4]})

df2 = pd.DataFrame({'Company': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B'], 'Date': ['01/04/2015', '01/06/2015', '01/13/2015', '01/05/2015', '01/06/2015', '01/11/2015', '01/14/2015', '01/05/2015', '01/07/2015', '01/13/2015', '01/14/2015', '01/03/2015', '01/11/2015', '01/14/2015'], 'Group': ['X', 'X', 'X', 'XX', 'XX', 'XX', 'XX', 'Y', 'Y', 'Y', 'Y', 'YY', 'YY', 'YY'], 'Value': [5, 10, 15, 6, 9, 9, 12, 4, 6, 16, 24, 10, 10, 12]})

for df in [df1, df2]:
    df['Date'] = pd.to_datetime(df['Date'])
    df['Week'] = df['Date'].values.astype('datetime64[W]')

result = pd.merge(df2, df1, how='left', on=['Week', 'Group', 'Company'], suffixes=['', '_1'])
result['Value/People'] = result['Value']/result['People']
result = result[['Company', 'Group', 'Date', 'Value/People']]
print(result)

产量

   Company Group       Date  Value/People
0        A     X 2015-01-04          1.00
1        A     X 2015-01-06          2.00
2        A     X 2015-01-13          1.50
3        A    XX 2015-01-05          1.00
4        A    XX 2015-01-06          1.50
5        A    XX 2015-01-11          0.75
6        A    XX 2015-01-14          1.00
7        B     Y 2015-01-05          1.00
8        B     Y 2015-01-07          1.50
9        B     Y 2015-01-13          2.00
10       B     Y 2015-01-14          3.00
11       B    YY 2015-01-03          2.00
12       B    YY 2015-01-11          2.50
13       B    YY 2015-01-14          3.00

请注意,裁剪日期为标准周时,需要考虑“基本偏移”问题。 换句话说,您需要确定一周的开始时间。 如果您不喜欢df['Date'].values.astype('datetime64[W]')做出的规范选择,则可能需要为日期添加偏移量。 例如,要将天添加到df['Date'] ,可以使用:

(df['Date'].values + np.timedelta64(1, 'D')).astype('datetime64[W]')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM