我在每日级别上有一列值,而在每周级别上有另一列值。我想将每日价值除以相应公司和集团当天的每周价值。我试图找出一种没有循环的方法,我觉得有一种方法可以在熊猫或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
答案 0 :(得分:1)
存储在DataFrames和Series中的类似日期的值的基础dtype是NumPy datetime64[ns]
。 datetime64[ns]
值的数组可以"裁剪"通过调用astype('datetime64[?]')
来规范第二,分钟,小时,日,周,月或年,其中?
由相应的单位替换(例如s
,m
,h
,D
,W
,M
,Y
)。
如果我们可以将每个日期分类为规范周,那么我们的问题将在很大程度上得到解决。我们可以使用.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
对df1
和df2
完成此操作后,我们现在可以合并['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
请注意,有#34;基本偏移"将种植日期缩短到规范周时需要考虑的问题。换句话说,您需要决定一周何时开始。如果您不喜欢df['Date'].values.astype('datetime64[W]')
所做的规范选择,则可能需要在日期中添加偏移量。例如,要将日期添加到df['Date']
中的日期,您可以使用:
(df['Date'].values + np.timedelta64(1, 'D')).astype('datetime64[W]')