在熊猫df中计算唯一值的循环

时间:2018-09-07 01:13:59

标签: python pandas loops unique

我正在尝试创建一个loop或更有效的过程,该过程可以count pandas df中的当前值。目前,我正在选择要对其执行功能的值。

因此对于下面的df,我试图确定两个counts

1)['u']返回['Code', 'Area']中剩余的相同剩余值的计数。因此,多少剩余时间出现相同的值。

2)['On']返回['Area']中当前出现的值量。它通过解析df来查看这些值是否再次出现来实现此目的。因此,从本质上来说,它可以展望未来是否再次出现这些价值。

import pandas as pd

d = ({
    'Code' : ['A','A','A','A','B','A','B','A','A','A'],            
    'Area' : ['Home','Work','Shops','Park','Cafe','Home','Cafe','Work','Home','Park'],  
     })

df = pd.DataFrame(data=d)

#Select value
df1 = df[df.Code == 'A'].copy()

df1['u'] = df1[::-1].groupby('Area').Area.cumcount()

ids = [1]
seen = set([df1.iloc[0].Area])
dec = False
for val, u in zip(df1.Area[1:], df1.u[1:]):
    ids.append(ids[-1] + (val not in seen) - dec)
    seen.add(val)
    dec = u == 0
df1['On'] = ids

df1 = df1.reindex(df.index).fillna(df1)

问题是我想在Code中的所有值上运行此脚本。而不是一次选择一个。例如,如果我想在Code['B']上执行相同的操作,则必须更改:df2 = df1[df1.Code == 'B'].copy(),然后再次运行脚本。

如果我在Code中有很多值,它将变得非常无效率。我需要一个loop,它可以在unique中找到所有'Code'的值,理想情况下,脚本应如下所示:

df1 = df[df.Code == 'All unique values'].copy()

预期输出:

  Code   Area    u   On
0    A   Home  2.0  1.0
1    A   Work  1.0  2.0
2    A  Shops  0.0  3.0
3    A   Park  1.0  3.0
4    B   Cafe  1.0  1.0
5    A   Home  1.0  3.0
6    B   Cafe  0.0  1.0
7    A   Work  0.0  3.0
8    A   Home  0.0  2.0
9    A   Park  0.0  1.0

3 个答案:

答案 0 :(得分:0)

GroupBysizecumcount结合使用,您可以构建u系列。

您对On的逻辑不清楚:这需要澄清。

g = df.groupby(['Code', 'Area'])
df['u'] = g['Code'].transform('size') - (g.cumcount() + 1)

print(df)

  Code   Area  u
0    A   Home  2
1    A   Home  1
2    B  Shops  1
3    A   Park  1
4    B   Cafe  1
5    B  Shops  0
6    A   Home  0
7    B   Cafe  0
8    A   Work  0
9    A   Park  0

答案 1 :(得分:0)

我发现您的“启用”逻辑非常令人困惑。就是说,我想我可以复制它:

df["u"] = df.groupby(["Code", "Area"]).cumcount(ascending=False)
df["nunique"] = pd.get_dummies(df.Area).groupby(df.Code).cummax().sum(axis=1)
df["On"] = (df["nunique"] - 
           (df["u"] == 0).groupby(df.Code).cumsum().groupby(df.Code).shift().fillna(0)

这给了我

In [212]: df
Out[212]: 
  Code   Area  u  nunique   On
0    A   Home  2        1  1.0
1    A   Work  1        2  2.0
2    A  Shops  0        3  3.0
3    A   Park  1        4  3.0
4    B   Cafe  1        1  1.0
5    A   Home  1        4  3.0
6    B   Cafe  0        1  1.0
7    A   Work  0        4  3.0
8    A   Home  0        4  2.0
9    A   Park  0        4  1.0

在此,u是该行之后的匹配对(代码,区域)对的数量。 nunique是该代码中到目前为止看到的唯一Area值的数量。 到目前为止,显示的是唯一区域的数量,除了一旦我们“用完”一个区域(一旦不再使用它),便开始从nuniq中减去它。

答案 2 :(得分:-1)

此过程将您的工作流应用于表中的每个代码:

def yourFunc(df1):
    df1['u'] = df1[::-1].groupby('Area').Area.cumcount()

    ids = [1]
    seen = set([df1.iloc[0].Area])
    dec = False
    for val, u in zip(df1.Area[1:], df1.u[1:]):
        ids.append(ids[-1] + (val not in seen) - dec)
        seen.add(val)
        dec = u == 0
    df1['On'] = ids

    df1 = df1.reindex(df.index).fillna(df)
    return(df1)

test = df.groupby('Code').apply(yourFunc)

测试:

        Area    Code u  On
Code                    
A   
    0   Home    A   2.0 1.0
    1   Home    A   1.0 1.0
    2   Shops   B   NaN NaN
    3   Park    A   1.0 2.0
    4   Cafe    B   NaN NaN
    5   Shops   B   NaN NaN
    6   Home    A   0.0 2.0
    7   Cafe    B   NaN NaN
    8   Work    A   0.0 2.0
    9   Park    A   0.0 1.0
B   
    0   Home    A   NaN NaN
    1   Home    A   NaN NaN
    2   Shops   B   1.0 1.0
    3   Park    A   NaN NaN
    4   Cafe    B   1.0 2.0
    5   Shops   B   0.0 2.0
    6   Home    A   NaN NaN
    7   Cafe    B   0.0 1.0
    8   Work    A   NaN NaN
    9   Park    A   NaN NaN