Python 查询按一个特征、多个条件分组的数据,并将其输出到列表中

Python 查询按一个特征、多个条件分组的数据,并将其输出到列表中,python,pandas,dataframe,Python,Pandas,Dataframe,我有下面的熊猫df虚拟df,原来的一个由100000个条目组成 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'],

我有下面的熊猫df虚拟df,原来的一个由100000个条目组成

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,我希望有一个正确的答案is_correct==1.0,然后是该id内伪随机选取的答案,最后是随机答案的is_correct值1.0或0.0


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

我想这就是您要找的:

>>> 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']]

我想这就是你想要的:

>>> 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']]
update-.applybool已替换为==1.0以处理“1.0”和“0.0”字符串


更新-.applybool被==1.0替换为处理“1.0”和“0.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]
我认为你可以放弃这个,你问题的其他逻辑更容易实现。您可以使用以下循环遍历分组为_df的结果数据帧行:

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

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

我不是一个熊猫专家,但我最近经常使用它。您可以使用以下代码对数据帧进行分组:

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]
我认为你可以放弃这个,你问题的其他逻辑更容易实现。您可以使用以下循环遍历分组为_df的结果数据帧行:

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

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

太好了,可以在虚拟df上工作!在我的df上,我得到一个索引器:无法从空序列错误中选择。但是,我仔细检查了一下,df中没有任何NAN。知道来源是什么吗?我想我发现了问题,我的伪df以索引0开始,但我的原始df以1开始。有趣的是,如果我不手动将索引添加到伪df,提供的代码将无法工作,因为它以0开始。然后,如果我做df.index=np.arange1,lendf+1,索引从1开始,但仍然不起作用。你知道为什么会这样吗?我根据这一点编辑了这个问题。好吧,我的朋友,唯一一次它不起作用,而你出现这个错误的原因是我假设给定id总是有一个正确的答案。所以在你的真实数据中,有一种可能性,对于某个id,“是正确的”下的所有值都是0.0现在Lior写的答案在这种情况下是错误的。看看他提供的答案。列表中的第二个列表是-['dog','dog','0.0']。狗是对的吗?不是吗?如果这是您想要的-如果没有一个值是正确的,那么该值不正确?如果你愿意,我可以强迫它这么做。您的呼叫。如果原始数据中的某个id没有is_correct=1.0,则肯定会发生此错误。如果你愿意,你可以得到一个字符串作为NONE-CORRECT打印回来,如果NONE是正确的!在我的df上,我得到一个索引器:无法从空序列错误中选择。但是,我仔细检查了一下,df中没有任何NAN。知道来源是什么吗?我想我发现了问题,我的伪df以索引0开始,但我的原始df以1开始。有趣的是,如果我不手动将索引添加到伪df,提供的代码将无法工作,因为它以0开始。然后,如果我做df.index=np.arange1,lendf+1,索引从1开始,但仍然不起作用。你知道为什么会这样吗?我根据这一点编辑了这个问题。好吧,我的朋友,唯一一次它不起作用,而你出现这个错误的原因是我假设给定id总是有一个正确的答案。所以在你的真实数据中,有一种可能性,对于某个id,“是正确的”下的所有值都是0.0现在Lior写的答案在这种情况下是错误的。看看他提供的答案。列表中的第二个列表是-['dog','dog','0.0']。狗是对的吗?不是吗?如果这是您想要的-如果没有一个值是正确的,那么该值不正确?如果你愿意,我可以强迫它这么做。您的呼叫。如果原始数据中的某个id没有is_correct=1.0,则肯定会发生此错误。如果你愿意,你可以得到一个字符串作为NONE-CORRECT打印回来,如果NONE是正确的!有趣的是,如果我不手动将索引添加到伪df,那么提供的代码将无法工作,因为我假设自动生成的索引以0开头。然后,如果我做df.index=np.arange1,lendf+1,索引从1开始,但仍然不起作用。你知道为什么会这样吗?我根据这一点编辑了问题。需要在第一个返回元素中添加iloc[0]。我
更新了答案列表中的第二个列表是['dog'、'dog'、'0.0'],但是对于任何一个'dog',is_correct值永远不会=1.0,那么这是正确的吗?很好,amit。0.0是一个字符串,bool'0.0'为真。修正为=='1.0'。酷,在虚拟df上工作!有趣的是,如果我不手动将索引添加到伪df,那么提供的代码将无法工作,因为我假设自动生成的索引以0开头。然后,如果我做df.index=np.arange1,lendf+1,索引从1开始,但仍然不起作用。你知道为什么会这样吗?我根据这一点编辑了问题。需要在第一个返回元素中添加iloc[0]。我更新了答案列表中的第二个列表是['dog'、'dog'、'0.0'],但是对于任何一个'dog',is_correct值永远都不会=1.0,那么这是正确的吗?抓得好,@amit。0.0是一个字符串,bool'0.0'为真。修正为=='1.0'。