如何计算 Python pandas 数据帧中 select 值的频率
How to count frequency of select values in Python pandas dataframe
我有一个包含两列的数据框,一列用于名称,一列用于字符串值。
我正在尝试按名称计算 select 字符串值的频率。
我试过 pandas.pivot_table 和 pandas.DataFrame.groupby 但我想创建一个全新的数据框而不是聚合。
例如,我有一个数据框:
import pandas as pd
import numpy as np
data = np.array([['John', 'x'], ['John', 'x'], ['John', 'x'], ['John', 'y'], ['John', 'y'], ['John', 'a'],
['Will', 'x'], ['Will', 'z']])
df = pd.DataFrame(data, columns=['name','str_value'])
df
这导致:
name str_value
0 John x
1 John x
2 John x
3 John y
4 John y
5 John a
6 Will x
7 Will z
预期结果为:
name x y z
0 John 3 2 0
1 Will 1 0 1
另外:
name x y z
0 John True True False
1 Will True False True
我只想 select x、y、z 和 return True 或 False 基于 returned 值是 0 还是 NaN。
编辑:
谢谢你的回答。
这些工作很好,但输出有子组 "str_value":
str_value x y z
name
John True True False
Will True False True
有没有办法删除它,让我的 "name"、"x"、"y"、"z" 处于同一水平?
使用 .reset_index() 我得到:
str_value name x y z
0 John True True False
1 Will True False True
现在我的索引名称"str_value"是吗?我可以重命名或删除它吗?
groupby
和 pivot
的混合:
total = df.groupby(["name", "str_value"]).size().reset_index(level=1, name="total")
counts = total.pivot(columns="str_value", values="total").fillna(0).drop(columns=["a"])
bools = counts > 0.0
你可以试试:
df.groupby(["name", "str_value"]).size().unstack()[['x', 'y', 'z']].gt(0)
说明:
print(df.groupby(["name", "str_value"]).size())
# John a 1
# x 3
# y 2
# Will x 1
# z 1
# dtype: int64
- 使用
unstack
取消堆叠
print(df.groupby(["name", "str_value"]).size().unstack())
# str_value a x y z
# name
# John 1.0 3.0 2.0 NaN
# Will NaN 1.0 NaN 1.0
- Select 所需列:
print(df.groupby(["name", "str_value"]).size().unstack()[['x', 'y', 'z']])
# str_value x y z
# name
# John 3.0 2.0 NaN
# Will 1.0 NaN 1.0
- 将大于 0 的值与
gt
进行比较:
result = df.groupby(["name", "str_value"]).size().unstack()[['x', 'y', 'z']].gt(0)
print(result)
# str_value x y z
# name
# John True True False
# Will True False True
除了其他出色的答案之外,您还可以混合使用 groupby
unstack
和 astype(bool)
作为一个衬里:
df1 = df.loc[df.str_value != 'a'] # remove a as requested.
df2 = df1.groupby(["name", "str_value"])["str_value"].count().unstack().fillna(False).astype(
bool)
print(df2)
name x y z
0 John True True False
1 Will True False True
我有一个包含两列的数据框,一列用于名称,一列用于字符串值。 我正在尝试按名称计算 select 字符串值的频率。
我试过 pandas.pivot_table 和 pandas.DataFrame.groupby 但我想创建一个全新的数据框而不是聚合。
例如,我有一个数据框:
import pandas as pd
import numpy as np
data = np.array([['John', 'x'], ['John', 'x'], ['John', 'x'], ['John', 'y'], ['John', 'y'], ['John', 'a'],
['Will', 'x'], ['Will', 'z']])
df = pd.DataFrame(data, columns=['name','str_value'])
df
这导致:
name str_value
0 John x
1 John x
2 John x
3 John y
4 John y
5 John a
6 Will x
7 Will z
预期结果为:
name x y z
0 John 3 2 0
1 Will 1 0 1
另外:
name x y z
0 John True True False
1 Will True False True
我只想 select x、y、z 和 return True 或 False 基于 returned 值是 0 还是 NaN。
编辑: 谢谢你的回答。 这些工作很好,但输出有子组 "str_value":
str_value x y z
name
John True True False
Will True False True
有没有办法删除它,让我的 "name"、"x"、"y"、"z" 处于同一水平? 使用 .reset_index() 我得到:
str_value name x y z
0 John True True False
1 Will True False True
现在我的索引名称"str_value"是吗?我可以重命名或删除它吗?
groupby
和 pivot
的混合:
total = df.groupby(["name", "str_value"]).size().reset_index(level=1, name="total")
counts = total.pivot(columns="str_value", values="total").fillna(0).drop(columns=["a"])
bools = counts > 0.0
你可以试试:
df.groupby(["name", "str_value"]).size().unstack()[['x', 'y', 'z']].gt(0)
说明:
print(df.groupby(["name", "str_value"]).size())
# John a 1
# x 3
# y 2
# Will x 1
# z 1
# dtype: int64
- 使用
unstack
取消堆叠
print(df.groupby(["name", "str_value"]).size().unstack())
# str_value a x y z
# name
# John 1.0 3.0 2.0 NaN
# Will NaN 1.0 NaN 1.0
- Select 所需列:
print(df.groupby(["name", "str_value"]).size().unstack()[['x', 'y', 'z']])
# str_value x y z
# name
# John 3.0 2.0 NaN
# Will 1.0 NaN 1.0
- 将大于 0 的值与
gt
进行比较:
result = df.groupby(["name", "str_value"]).size().unstack()[['x', 'y', 'z']].gt(0)
print(result)
# str_value x y z
# name
# John True True False
# Will True False True
除了其他出色的答案之外,您还可以混合使用 groupby
unstack
和 astype(bool)
作为一个衬里:
df1 = df.loc[df.str_value != 'a'] # remove a as requested.
df2 = df1.groupby(["name", "str_value"])["str_value"].count().unstack().fillna(False).astype(
bool)
print(df2)
name x y z
0 John True True False
1 Will True False True