创建一个数据帧,该数据帧由来自另一行的所有行对组成

2024-06-16 10:01:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个DF,它有两列:问题和答案。“答案”列包含重复项

我现在想创建一个新的DF,它有三列:问题1,问题2,重复

问题1和问题2列将填充为初始DF中所有问题的每个唯一组合。重复列将是布尔值,对应于问题在初始DF中是否有相同的答案

初始DF约为13000行,因此生成的DF将很大(我认为对于我的机器上的Pandas来说太大了,但我可以减少初始DF以进行测试,然后如果我需要所有数据,可以更改为Pandas以外的数据)

有没有比O(N^2)嵌套循环更快的方法,例如,如果没有并行化/矢量化,这需要花费太长的时间:

questions1, questions2, duplicates = [], [], []

for i in range(len(dataset)-1):
    print(f'{i+1} / {len(dataset)-1}')
    question1 = dataset.iloc[i]['question']
    answer1 = dataset.iloc[i]['answer']
    for j in range(i+1, len(dataset)):
        question2 = dataset.iloc[j]['question']
        answer2 = dataset.iloc[j]['answer']
        duplicate = answer1 == answer2
        questions1.append(question1)
        questions2.append(question2)
        duplicates.append(duplicate)

duplicate_dataset = pd.DataFrame({
    'question1': questions1,
    'question2': questions2,
    'duplicate': duplicates
})

编辑:根据要求,这里是输入DF的玩具示例:

df = pd.DataFrame({
    'question': ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yzz'],
    'answer': ['1', '2', '1', '3', '4', '4', '5', '1', '6']
})

结果DF应该等于:

df2 = pd.DataFrame({
    'question1': [
        'abc', 'abc', 'abc', 'abc',
        'abc', 'abc', 'abc', 'abc',
        'def', 'def', 'def', 'def',
        'def', 'def', 'def', 'ghi',
        'ghi', 'ghi', 'ghi', 'ghi',
        'ghi', 'jkl', 'jkl', 'jkl',
        'jkl', 'jkl', 'mno', 'mno',
        'mno', 'mno', 'pqr', 'pqr',
        'pqr', 'stu', 'stu', 'vwx'
    ],
    'question2': [
        'def', 'ghi', 'jkl', 'mno',
        'pqr', 'stu', 'vwx', 'yzz',
        'ghi', 'jkl', 'mno', 'pqr',
        'stu', 'vwx', 'yzz', 'jkl',
        'mno', 'pqr', 'stu', 'vwx',
        'yzz', 'mno', 'pqr', 'stu',
        'vwx', 'yzz', 'pqr', 'stu',
        'vwx', 'yzz', 'stu', 'vwx',
        'yzz', 'vwx', 'yzz', 'yzz'
    ],
    'duplicate': [
        False, True, False, False,
        False, False, True, False,
        False, False, False, False,
        False, False, False, False,
        False, False, False, True,
        False, False, False, False,
        False, False, True, False,
        False, False, False, False,
        False, False, False, False
    ]
})

Tags: falsedfdefjkldatasetabcduplicatestu
2条回答

使用^{}^{}有一种方法:

from itertools import combinations

# Create mapping Series of questions - answers
q_map = df.drop_duplicates(subset='question').set_index('question')['answer']

# Create DataFrame of all combinations of questions
df2 = pd.DataFrame(combinations(df['question'].unique(), 2), columns=['question1', 'question2'])

# Create duplicate field using the helper mapping Series
df2['duplicate'] = df2['question1'].map(q_map) == df2['question2'].map(q_map)

[外]

   question1 question2  duplicate
0        abc       def      False
1        abc       ghi       True
2        abc       jkl      False
3        abc       mno      False
4        abc       pqr      False
5        abc       stu      False
6        abc       vwx       True
7        abc       yzz      False
8        def       ghi      False
9        def       jkl      False
10       def       mno      False
11       def       pqr      False
12       def       stu      False
13       def       vwx      False
14       def       yzz      False
15       ghi       jkl      False
16       ghi       mno      False
17       ghi       pqr      False
18       ghi       stu      False
19       ghi       vwx       True
20       ghi       yzz      False
21       jkl       mno      False
22       jkl       pqr      False
23       jkl       stu      False
24       jkl       vwx      False
25       jkl       yzz      False
26       mno       pqr       True
27       mno       stu      False
28       mno       vwx      False
29       mno       yzz      False
30       pqr       stu      False
31       pqr       vwx      False
32       pqr       yzz      False
33       stu       vwx      False
34       stu       yzz      False
35       vwx       yzz      False

这里还有另一个解决方案,它仍然依赖于itertools.combinationszip

将df.question和df.answer组合在一起,使用组合创建非重复的对,使用列表理解来获得真或假的对,最后使用输出创建一个新的数据帧

from itertools import combinations
#zip columns, then combine
M = (combinations(zip(df.question,df.answer),2))

#list comprehension here to get ur True or False entries
outcome = [(i[0],j[0],True) 
            if i[-1]==j[-1] else (i[0],j[0],False) 
            for i, j in M]

 #create new dataframe
new_df = pd.DataFrame(outcome,columns= ['question1','question2','duplicate'])

相关问题 更多 >