熊猫有可能吗?

时间:2018-06-19 22:53:28

标签: pandas

我有一个看起来像这样的数据集:

Date        COL1    COL2    COL3
2017/01/01   123      A       N
2017/01/01   234      A       N
2017/01/01   567      A       Y
2017/01/01   111      B       N
2017/01/02   123      A       Y
2017/01/02   999      A       N
2017/01/02   333      A       Y
2017/01/02   444      B       N
2017/01/02   555      B       Y

所需的输出

Date        COL2  Count
2017/01/01   A      1
2017/01/01   B      1
2017/01/02   A      0
2017/01/02   B      1

所需输出的说明:

我想对属于COL2中特定组的COL1行求和,并且仅在COL3的值为N时才求和,而如果COL3的Y则求和。

(它应该是滚动总和,其中当前计算是基于上一个日期和今天的日期之和)

我想出了一个python脚本,该脚本首先创建一个地图,键是COL2,值是日期和COL1的元组。 然后,脚本循环遍历整个数据集,在此过程中,如果当前行不在地图中,则将当前行添加到地图中;如果在地图中,则将其追加。
然后,我仅遍历创建的地图,并检查每个条目的大小以得出计数。

但是,我想学习如何使用熊猫来做到这一点,我曾尝试使用分组和聚合,但无法获得正确的格式。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

假设您同时按“日期”和“ COL2”分组,这是一个统一的解决方案:

创建数据框:

>>> import pandas as pd
>>> df = pd.DataFrame({'Date': ['2017/01/01', '2017/01/01', '2017/01/01', '2017/01/02', '2017/01/02', '2017/01/02'], 
                   'COL1': [123, 234, 135, 123, 135, 246], 
                   'COL2': ['A', 'A', 'B', 'A', 'B', 'B'], 
                   'COL3': ['N', 'N', 'Y', 'N', 'N', 'Y']})
>>> df
    Date        COL1    COL2    COL3
0   2017/01/01  123     A       N
1   2017/01/01  234     A       N
2   2017/01/01  135     B       Y
3   2017/01/02  123     A       N
4   2017/01/02  135     B       N
5   2017/01/02  246     B       Y

一个班轮代码:

>>> df.join(((df.COL3 == 'N')*2 - 1).rename('Count').to_frame()).groupby(['Date','COL2']).Count.sum().groupby(level=[1]).cumsum().reset_index()
        Date    COL2    Count
0   2017/01/01  A       2
1   2017/01/01  B       -1
2   2017/01/02  A       3
3   2017/01/02  B       -1

说明:

我首先通过从COL3得出总和值来创建另一列,将其命名为Count,然后进行分组sum以获取每个{{1} },Date组合,最后是COL2级别的分组cumsum来获得滚动计数。

答案 1 :(得分:1)

解决方案将在列上的groupby之后在pandas中创建一个自定义聚合器。

>> from pandas import DataFrame as df
>>> df_ = df({'col': [1, 1, 1, 2, 2, 2], 'a': ['A', 'A', 'B', 'A', 'B', 'B'], 'b': ['N', 'N', 'Y', 'Y', 'N', 'Y']})
>> df_
   a  b  col
0  A  N    1
1  A  N    1
2  B  Y    1
3  A  Y    2
4  B  N    2
5  B  Y    2
>> f = lambda a: list(a).count('N')-list(a).count('Y') # custom aggregation after grouping
>> agg_df = df_.groupby(['col', 'a']).agg({'b': f}).reset_index()
>> agg_df
   col  a  b
0    1  A  2
1    1  B -1
2    2  A -1
3    2  B  0

希望这会有所帮助。