Python 使用Pandas移动分类值窗口
我有这样一个熊猫系列:Python 使用Pandas移动分类值窗口,python,pandas,Python,Pandas,我有这样一个熊猫系列: s = pd.Series(["A", "A", "B", "C", "A", "C", "A", "C", "A", "B", "B", "B", "A", "A", "C"]) 我想把每个字母的数量或比例放在一个不重叠的4号窗口中 我试过这个: pd.rolling_apply(s, 4, pd.value_counts) 但它不起作用 ValueError: could not convert string to float: C 执行这项任务有什么想法吗?好
s = pd.Series(["A", "A", "B", "C", "A", "C", "A", "C", "A", "B", "B", "B", "A", "A", "C"])
我想把每个字母的数量或比例放在一个不重叠的4号窗口中
我试过这个:
pd.rolling_apply(s, 4, pd.value_counts)
但它不起作用
ValueError: could not convert string to float: C
执行这项任务有什么想法吗?好主意!
我使用for循环获取所有窗口的字典。然后我构建一个数据帧,然后我可以使用value_counts()。这是你要的吗
In [150]: winsize = 4
In [151]: for i in range(len(s)+1-winsize): wd[i] = s[i:i+winsize].tolist()
In [152]: wd
Out[152]:
{0: ['A', 'A', 'B', 'C'],
1: ['A', 'B', 'C', 'A'],
2: ['B', 'C', 'A', 'C'],
3: ['C', 'A', 'C', 'A'],
4: ['A', 'C', 'A', 'C'],
5: ['C', 'A', 'C', 'A'],
6: ['A', 'C', 'A', 'B'],
7: ['C', 'A', 'B', 'B'],
8: ['A', 'B', 'B', 'B'],
9: ['B', 'B', 'B', 'A'],
10: ['B', 'B', 'A', 'A'],
11: ['B', 'A', 'A', 'C']}
In [153]: pd.DataFrame(wd)
Out[153]:
0 1 2 3 4 5 6 7 8 9 10 11
0 A A B C A C A C A B B B
1 A B C A C A C A B B B A
2 B C A C A C A B B B A A
3 C A C A C A B B B A A C
In [154]: pd.DataFrame(wd).apply(pd.value_counts)
Out[154]:
0 1 2 3 4 5 6 7 8 9 10 11
A 2 2 1 2 2 2 2 1 1 1 2 2
B 1 1 1 NaN NaN NaN 1 2 3 3 2 1
C 1 1 2 2 2 2 1 1 NaN NaN NaN 1
由于您的系列使用的是
范围索引
,因此您可以通过除以其大小来创建非重叠窗口:
print(s.index // 4)
# => Int64Index([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3], dtype='int64')
按上述内容分组并使用.value\u counts()
:
如果您喜欢比例而不是计数,请给出参数normalize=True
:
s.groupby(s.index // 4).value_counts(normalize=True)
# 0 A 0.500000
# B 0.250000
# C 0.250000
# 1 A 0.500000
# C 0.500000
# 2 B 0.750000
# A 0.250000
# 3 A 0.666667
# C 0.333333
# dtype: float64
如果您的系列具有不同类型的索引,您仍然可以按如下方式生成窗口:
pd.Series(range(len(s))) // 4
# 0 0
# 1 0
# 2 0
# 3 0
# 4 1
# 5 1
# 6 1
# 7 1
# 8 2
# 9 2
# 10 2
# 11 2
# 12 3
# 13 3
# 14 3
# dtype: int64
以下两行中的任何一行产生与上述相同的输出:
s.groupby(pd.Series(range(len(s))) // 4).value_counts()
s.groupby(pd.Series(range(len(s))) // 4).value_counts(normalize=True)
谢谢,我去看看。我只是想要不重叠的窗口,但我想这不是pb,你只需要在范围内添加一个步骤。
s.groupby(pd.Series(range(len(s))) // 4).value_counts()
s.groupby(pd.Series(range(len(s))) // 4).value_counts(normalize=True)