从Pandas数据框生成三胞胎

时间:2018-07-30 18:28:03

标签: python pandas machine-learning

我正在尝试根据类或标签从Pandas数据框中生成所有三元组数据。假设我有一个数据帧,每一行都有唯一的标识符,每行都有一个类/标签。我想要三胞胎,其中前两个元素来自相同的类/标签,而最后一个元素来自不同的类/标签。我正在尝试获取所有 这样的三胞胎。

我可以很好地生成带有 same 标签的元素组合,但是当我尝试使用带有 different 标签的元素扩展这些元素的组合时,我得到了一个数组充满None

我的示例数据框:

import pandas as pd
import numpy as np

df = pd.DataFrame({'uuid': np.arange(5),
                   'label': [0, 1, 1, 0, 0]})
print(df)

   label  uuid
0      0     0
1      1     1
2      1     2
3      0     3
4      0     4

请注意,uuid列只是此处的占位符。重点是每一行都是唯一的。下面的代码生成 same 元素的所有组合,并将它们插入列表:

import itertools as it

labels = df.label.unique()
all_combos = []
for l in labels:
    combos = list(it.combinations(df.loc[df.label == l].as_matrix(), 2))
    all_combos.extend([list(c) for c in combos])  # convert to list because I anticipate needing to add to each combo later
all_combos

[[array([0, 0]), array([0, 3])],
 [array([0, 0]), array([0, 4])],
 [array([0, 3]), array([0, 4])],
 [array([1, 1]), array([1, 2])]]

现在,我希望所有这些组合都附加每个不同元素。

我尝试:

for l in labels:
    combos = list(it.combinations(df.loc[df.label == l].as_matrix(), 2))
    combo_list = [list(c) for c in combos]
    for c in combo_list:
        new_combos = [list(c).extend(s) for s in df.loc[df.label != l].as_matrix()]
        all_combos.append(new_combos)

我希望:

all_combos

[[array([0, 0]), array([0, 3]), array([1, 1])],
 [array([0, 0]), array([0, 3]), array([1, 2])],
 [array([0, 0]), array([0, 4]), array([1, 1])],
 [array([0, 0]), array([0, 4]), array([1, 2])],
 [array([0, 3]), array([0, 4]), array([1, 1])],
 [array([0, 3]), array([0, 4]), array([1, 2])],
 [array([1, 1]), array([1, 2]), array([0, 0])],
 [array([1, 1]), array([1, 2]), array([0, 3])],
 [array([1, 1]), array([1, 2]), array([0, 4])]]

我得到:

all_combos

[[None, None], [None, None], [None, None], [None, None, None]]

看起来真的很奇怪:它们的长度甚至都不相同!但是我的结果中确实有None的数量与预期的有效三元组数量相同。

我还尝试了all_combos.extend(new_combos)并获得了9个元素的一维列表,因此上面的结果只是一个扁平化的版本。实际上,在内循环的最后两行中list.extendlist.append的任何组合都给我上面显示的结果,或者该结果的简化版本,这对我来说都不有意义。< / p>

编辑:如注释中所述,list.extendlist.append是就地操作,因此它们不会返回任何内容。然后我如何获得列表理解力来赋予我这些价值观?还是重构为其他可行的方法?

1 个答案:

答案 0 :(得分:0)

我明白了。如果有人遇到类似问题,我将在此处保留,但正如评论中所述,问题是list.appendlist.extend是就地操作,因此返回None ,甚至在列表理解之内。

我可以通过使用np.concatenate将我的数组混在一起来解决此问题:

for l in labels:
    combos = list(it.combinations(df.loc[df.label == l].as_matrix(), 2))
    for c in combos:
        new_combos = [np.concatenate((c, (s,)), axis=0) for s in df.loc[df.label != l].as_matrix()]
        all_combos.extend(new_combos)

此外,列表理解中的np.append(c, (s,), axis=0)也有效。