查询按一个特性、多个条件分组的pandas-df,并将其输出到列表中



我有以下pandas-df(伪df,原始的由100'000个条目组成(。

columns = ['id', 'answer', 'is_correct']
data = [['1','hello','1.0'],
['1','hello', '1.0'],
['1','bye', '0.0'],
['2', 'dog', '0.0'],
['2', 'cat', '1.0'],
['2', 'dog', '0.0'],
['3', 'Milan', '1.0'],
['3', 'Paris', '0.0'],
['3', 'Paris', '0.0'],
['3', 'Milan', '1.0']]
df = pd.DataFrame(columns=columns, data=data)
df
id   answer  is_correct
0   1   hello   1.0
1   1   hello   1.0
2   1   bye     0.0
3   2   dog     0.0
4   2   cat     1.0
5   2   dog     0.0
6   3   Milan   1.0
7   3   Paris   0.0
8   3   Paris   0.0
9   3   Milan   1.0

目标是根据条件创建一个列表列表。

条件:对于每个唯一的id,我希望有一个正确的answer(is_correct == 1.0(,然后在该id中有一个(伪(随机选取的answer,最后是随机answeris_correct值(1.0或0.0(。

[['hello', 'bye', 0.0], ['cat', 'dog', 0.0], ['Milan', 'Milan', 1.0], ...]]

我只需要每个唯一id中的两个答案。所有id都包含2个以上的答案。任何列中都没有NaN。

def filt(grp):
is_correct = grp['is_correct']=='1.0'
if is_correct.any():
sample = grp.sample()
return [grp['answer'][is_correct].iloc[0],
sample['answer'].to_list()[0],
sample['is_correct'].to_list()[0]]
print(df.groupby('id').apply(filt).to_list())  # --> [['hello', 'bye', '0.0'], ['dog', 'dog', '0.0'], ['Milan', 'Milan', '1.0']]

更新-用==1.0替换.apply(bool)以处理'1.0''0.0'字符串

我想这就是您想要的:

>>> import random
>>> keep = []
>>> for val in df.id.unique():
>>>     temp_keep = []
>>>     temp_df_correct = df[(df.id==val) & (df.is_correct=='1.0')]
>>>     temp_df_notcorrect = df[(df.id==val) & (df.is_correct=='0.0')]
>>>     correct_index = random.choice(temp_df_correct.index)
>>>     temp_keep.append(temp_df_correct.loc[correct_index,'answer'])
>>>     temp_df_correct.drop(correct_index, inplace=True)

>>>     new_df = temp_df_correct.append(temp_df_notcorrect, ignore_index=True, sort=False)
>>>     temp_keep.extend(random.choice(new_df[['answer', 'is_correct']].values))
>>>     keep.append(temp_keep)
>>> print(keep)
[['hello', 'bye', '0.0'], ['cat', 'dog', '0.0'], ['Milan', 'Milan', '1.0']]

我不是熊猫专家,但最近我用了很多。您可以使用以下代码对数据帧进行分组:

grouped_df = df.groupby(["id"])[["answer", "is_correct"]].agg(list)

之后,每行将按id:分组

answer            is_correct
id                                                    
1            [hello, hello, bye]       [1.0, 1.0, 0.0]
2                [dog, cat, dog]       [0.0, 1.0, 0.0]
3   [Milan, Paris, Paris, Milan]  [1.0, 0.0, 0.0, 1.0]

我认为你可以从中抽身,你问题的其余逻辑更容易实现。您可以使用以下循环迭代生成的数据帧grouped_df的行:

for row in grouped_df.iterrows():
print(row[1]["answer"])
print(row[1]["is_correct"])

希望能有所帮助。也许有一种更矢量化的方法可以做到这一点,但正如我之前所说,我不是专家。

最新更新