我正在尝试创建一个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
答案 0 :(得分:0)
将GroupBy
与size
和cumcount
结合使用,您可以构建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