我有以下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
,最后是随机answer
的is_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"])
希望能有所帮助。也许有一种更矢量化的方法可以做到这一点,但正如我之前所说,我不是专家。