【问题标题】:Python Pandas: How to find patterns of combinations (Combinations of Combinations) - time seriesPython Pandas:如何找到组合模式(组合的组合) - 时间序列
【发布时间】:2021-02-07 12:49:09
【问题描述】:

从这里开始:unique combinations of values in selected columns in pandas data frame and count

我发现使用此代码的 3 列出现次数最多到最少的组合:

def common_cols(df,n):
    '''n is how many of the top results to show'''

    df = df.groupby(['A','B','C']).size().reset_index().rename(columns={0:'count'})

    df = df.sort_values(by='count', ascending=False).reset_index(drop=True).head(n)

    return df

common_data = common_cols(df,10)

common_data 的输出(显示前 10 个结果):

      A     B       C      count
0    0.00  0.00    0.00     96
1    0.00  1.00    0.00     25
2    0.14  0.86    0.00     19
3    0.13  0.87    0.00     17
4    0.00  0.72    0.28     17
5    0.00  0.89    0.11     16
6    0.01  0.84    0.15     16
7    0.03  0.97    0.00     15
8    0.35  0.65    0.00     15
9    0.13  0.79    0.08     14 

现在,我想找出 A B C 行的组合,并计算它们出现了多少次。

例如,让我们在第 1 行到第 4 行的 BASE df 中说:

3 列的第一组组合(在使用 common_cols 函数之前由 dataframe(df) 告知)是

# each of these rows are their own combination of values
       A    B     C
0    0.67  0.16  0.17
1    0.06  0.73  0.20
2    0.19  0.48  0.33
3    0.07  0.87  0.06
4    0.07  0.60  0.33

以上 5 行(按顺序)将被计为一个组合模式。它可以算作 2 行、3 行、4 行或更多行的组合(如果这样做很容易的话!)

如果这个模式被找到一次(在整个数据帧中),它会输出这个模式的计数为 1。如果它被找到 10 次;计数将是 10。

关于如何计算连续行之间的组合有什么想法吗? 就像使用 common_cols 函数一样,但是作为“组合的组合”?

行必须是为了使它成为一个模式。非常感谢任何帮助!

【问题讨论】:

  • 我不确定这是否是正确的方法,但可能会有所帮助:您可以(迭代地)将列添加到包含下 N 行值列表的每一行。例如,第 0 行的 N_5 列包含 [row0, row1, row2, row3, row4]。然后,对于这些列中的每一列,您可以将所有这些列与其各自的计数列连接起来,并按函数进行分组。这有意义吗?
  • 你在计算 a,b,c 值的频率吗?如果是这样,一个组和大小应该可以工作。你还需要什么?
  • @JarroVGIT 我不确定,尤其是因为这是我第一次使用 groupby。感谢您的帮助和想法:)。 Rick M 的答案似乎是一个可行的解决方案
  • @GoldenLion 问题是关于计算发现连续模式的次数。例如,如果在数据集中找到数字(按顺序):0.5、0.25、0.25 和 0.2、0.8、0.0 多次,我正在寻找这样的模式
  • 使用 value_counts 或 Counter 获取组合或 groupby 大小的唯一计数

标签: python pandas dataframe combinations permutation


【解决方案1】:

我在这个测试数据帧中使用了整数,但如果你的 groupby 在上面工作,这也应该适用于你的数据:

df_size = 1000000
df = pd.DataFrame( { 'A' : (np.random.randint(20) for i in range(df_size)),
                     'B' : (np.random.randint(20) for i in range(df_size)),
                     'C' : (np.random.randint(20) for i in range(df_size)),
            })

print(df.head())
    A   B   C
0  12  12   5
1  19  12  12
2  14  11  15
3  11  14   8
4  13  16   2

下面的代码使用zip 列出了一个名为source 的三元组(A、B、C)列表。 tmp 变量(生成器)实际上是一个列表,其中包含源列表的连续“移位”副本,例如 [source[0:], source[1:], source[2:]...]

最后,ziptmp 中列表中的值交错,例如,对于n=2,它将生成一个列表 [(source[0], source[1]), (source[1], source[2]), ... ]

source = list(zip(df['A'],df['B'],df['C']))
n_consecutive = 3

tmp = ( source[i:] for i in range(n_consecutive) )
output = pd.Series(list(zip(*tmp)))

对于本例,这是一个包含三元组(A、B、C)值计数的序列:

print(output.value_counts().head())
((6, 19, 14), (19, 12, 6), (13, 7, 10))    2
((2, 18, 12), (17, 2, 19), (7, 19, 19))    1
((10, 2, 3), (1, 18, 8), (3, 6, 19))       1
((16, 15, 14), (11, 2, 9), (14, 14, 8))    1
((3, 3, 7), (13, 9, 3), (18, 15, 6))       1
dtype: int64

请注意,这可能会根据您要查找的内容重复计算。例如,如果基础 df 连续有 3 条记录,并且您正在寻找 2 个连续的模式:

(1, 3, 4)
(1, 3, 4)
(1, 3, 4)

在这种情况下,它会找到(1, 3, 4), (1, 3, 4) 两次。

【讨论】:

  • 很棒的人非常感谢你。我不确定双重计数,但与我运行以获得相同结果的不同代码相比,它似乎可以正常工作(我的方法非常笨拙,你的方法是天赐之物)。赞赏:)
  • 您知道如何在您的代码中实现 np.isclose() 解决方案吗?或者这是我必须首先做的事情?
  • 不客气!您可以在分组之前将值截断到所需的精度级别,这可能会起作用,或者可能使用np.histogramdd 预先对数据进行分箱...如果这不起作用,您可能想提出一个单独的问题。如果您愿意继续这个,请单击绿色复选标记将其标记为“已接受”。这有助于将注意力集中在仍然没有答案的旧 SO 问题上。谢谢,保重。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多