Python Pandas 中的 DataFrame 聚合?
Aggregation of DataFrame in Python Pandas?
我有如下所示的 DataFrame:
df = pd.DataFrame({"ID" : ["1", "1", "1", "2", "2", "2", "1"],
"status" : ["ac", "not", "not", "ac", np.NaN, "ac", "oth"]})
我需要使用如下列构建 DataFrame:
- NumberAcc - 状态为“ac”的 ID 数量
- NumberNaN - 状态为 NanN 的 ID 数量(缺失 -> np.nan)
- NumberOther - 状态不是“ac”或np.nan(表示“not”或“oth”)的 ID 的数量
你能帮我像下面这样构建 DF 吗?
您可以使用条件掩码将任何不是 ac 或 np.nan
的内容替换为 Other
和 groupby.value_counts
,然后使用 add_prefix
[=18 取消堆叠和格式化=]
u = df['status'].where(df['status'].eq("ac")|df['status'].isna(),"Other")
out = (u.groupby(df['ID']).value_counts(dropna=False).unstack(fill_value=0)
.add_prefix("Number_").reset_index().rename_axis(None,axis=1))
或;
a = pd.Series(np.select([df['status'].eq("ac"),df['status'].isna()],
['acc',np.nan],'other'))
out = (a.groupby(df['ID']).value_counts(dropna=True).unstack(fill_value=0)
.add_prefix("Numnber_").reset_index())
print(out)
ID Number_nan Number_Other Number_ac
0 1 0 3 1
1 2 1 0 2
@Shubham 建议的类似逻辑,但带有交叉表:
u = df['status'].where(df['status'].eq("ac")|df['status'].isna(),"Other")
out = (pd.crosstab(df['ID'],u.fillna("NAN"),dropna=False)
.add_prefix("Number_").rename_axis(None).reset_index())
您可以通过 assign 创建列,然后在 'ID' 上分组并求和:
(df.assign(NumberAcc=df.status.eq("ac"),
NumberNaN=df.status.isna(),
NumberOther=lambda df: ~(df.NumberAcc | df.NumberNaN))
.groupby("ID")
.sum())
NumberAcc NumberNaN NumberOther
ID
1 1 0 3
2 2 1 0
我有如下所示的 DataFrame:
df = pd.DataFrame({"ID" : ["1", "1", "1", "2", "2", "2", "1"],
"status" : ["ac", "not", "not", "ac", np.NaN, "ac", "oth"]})
我需要使用如下列构建 DataFrame:
- NumberAcc - 状态为“ac”的 ID 数量
- NumberNaN - 状态为 NanN 的 ID 数量(缺失 -> np.nan)
- NumberOther - 状态不是“ac”或np.nan(表示“not”或“oth”)的 ID 的数量
你能帮我像下面这样构建 DF 吗?
您可以使用条件掩码将任何不是 ac 或 np.nan
的内容替换为 Other
和 groupby.value_counts
,然后使用 add_prefix
[=18 取消堆叠和格式化=]
u = df['status'].where(df['status'].eq("ac")|df['status'].isna(),"Other")
out = (u.groupby(df['ID']).value_counts(dropna=False).unstack(fill_value=0)
.add_prefix("Number_").reset_index().rename_axis(None,axis=1))
或;
a = pd.Series(np.select([df['status'].eq("ac"),df['status'].isna()],
['acc',np.nan],'other'))
out = (a.groupby(df['ID']).value_counts(dropna=True).unstack(fill_value=0)
.add_prefix("Numnber_").reset_index())
print(out)
ID Number_nan Number_Other Number_ac
0 1 0 3 1
1 2 1 0 2
@Shubham 建议的类似逻辑,但带有交叉表:
u = df['status'].where(df['status'].eq("ac")|df['status'].isna(),"Other")
out = (pd.crosstab(df['ID'],u.fillna("NAN"),dropna=False)
.add_prefix("Number_").rename_axis(None).reset_index())
您可以通过 assign 创建列,然后在 'ID' 上分组并求和:
(df.assign(NumberAcc=df.status.eq("ac"),
NumberNaN=df.status.isna(),
NumberOther=lambda df: ~(df.NumberAcc | df.NumberNaN))
.groupby("ID")
.sum())
NumberAcc NumberNaN NumberOther
ID
1 1 0 3
2 2 1 0