有以下数据框df
:
df =
ID_DATA FD_1 FD_2 FD_3 FD_4 GRADE
111 23 12 34 45 1
111 23 67 45 5
111 12 67 45 23 5
222 23 55 66 4
222 55 66 4
我计算了每ID_DATA
的频率如下:
freq = df.ID_DATA.value_counts().reset_index()
freq =
ID_DATA FREQ
111 3
222 2
但是,我需要更改此计算的逻辑如下。有两个列表具有不同的FD_*
值:
BaseList = [23,34]
AdjList = [12,45,67]
我需要计算df
中这两个列表中值的出现频率。但是有一些规则:
1)如果某行包含属于FD_*
的{{1}}的任何值,则不应计算AdjList
。只有当一行不包含BaseList
中的任何值时,才应对BaseList
进行计数。
2)如果某行包含多个AdjList
值,则应将其计为+1。
3)如果某行包含多个BaseList
值,则只应计算最后一列AdjList
。
结果应该是这个:
FD_*
ID_DATA FREQ_BaseList FREQ_12 FREQ_45 FREQ_67
111 0 0 3 0
222 1 0 0 0
的{{1}}值等于0,因为触发了规则#1。
答案 0 :(得分:1)
我们的想法是为此创建自定义功能,然后根据需要进行调整。你当然可以通过替换硬编码列列来使它更漂亮:
>>> def worker1(x):
... b = 0
... for v in x:
... if v in AdjList:
... return ['FREQ_' + str(int(v)), 1]
... else:
... b = b + BaseList.count(v)
... return ('FREQ_BaseList', b)
...
>>> def worker2(x):
... r = worker1(x[['FD_4','FD_3','FD_2','FD_1']])
... return pd.Series([x['ID_DATA'], r[1]], index=['ID_DATA', r[0]])
...
>>> res = df.apply(worker2, axis=1).groupby('ID_DATA').sum()
>>> res
FREQ_45 FREQ_BaseList
ID_DATA
111.0 3.0 NaN
222.0 NaN 1.0
>>> res.reindex(columns=['FREQ_BaseList','FREQ_12','FREQ_45','FREQ_67']).fillna(0).astype(int)
FREQ_BaseList FREQ_12 FREQ_45 FREQ_67
ID_DATA
111.0 0 0 3 0
222.0 1 0 0 0