Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按从组外收集值列表_Python_Pandas - Fatal编程技术网

Python 按从组外收集值列表

Python 按从组外收集值列表,python,pandas,Python,Pandas,我有一个数据框: df ID值 0 1 0.33 1 1 0.91 2 1 0.28 3 2 0.36 4 2 0.50 5 3 0.47 6 3 0.98 7 3 0.34 8 3 0.37 我想按ID分组并创建两个新列: “values_in”是ID的值列列表 “values_out”是其他ID的值列列表 输出如下: ID values_in

我有一个数据框:

df
ID值
0   1   0.33
1   1   0.91
2   1   0.28
3   2   0.36
4   2   0.50
5   3   0.47
6   3   0.98
7   3   0.34
8   3   0.37
我想按ID分组并创建两个新列:

  • “values_in”是ID的值列列表
  • “values_out”是其他ID的值列列表
  • 输出如下:

    
       ID                 values_in                                  values_out
    0   1        [0.33, 0.91, 0.28]         [0.36, 0.5, 0.47, 0.98, 0.34, 0.37]
    1   2               [0.36, 0.5]  [0.33, 0.91, 0.28, 0.47, 0.98, 0.34, 0.37]
    2   3  [0.47, 0.98, 0.34, 0.37]               [0.33, 0.91, 0.28, 0.36, 0.5]
    
    知道如果我使用经典的
    groupby
    我会自动排除
    值,我该怎么做


    仅供参考:我不关心列表中的顺序。

    ID
    上使用
    groupby
    ,并在列表中为每个分组帧创建相应键为
    ID
    values\u in
    values\u out
    的字典:

    d = [{'ID': k,
          'values_in': g['Value'].values,
          'values_out': df.loc[df['ID'].ne(k), 'Value'].values}
         for k, g in df.groupby('ID')]
    df_ = pd.DataFrame(d)
    
    结果:

       ID                 values_in                                  values_out
    0   1        [0.33, 0.91, 0.28]         [0.36, 0.5, 0.47, 0.98, 0.34, 0.37]
    1   2               [0.36, 0.5]  [0.33, 0.91, 0.28, 0.47, 0.98, 0.34, 0.37]
    2   3  [0.47, 0.98, 0.34, 0.37]               [0.33, 0.91, 0.28, 0.36, 0.5]
    
    计时(使用包含100个唯一
    ID
    的数据帧进行测试):


    使用matmul的单向方式:

    new_df = df.groupby("ID")["Value"].apply(list).reset_index(name="values_in")
    new_df["values_out"] = new_df["values_in"] @ (1 - np.eye(new_df.shape[0], dtype=int))
    print(new_df)
    
    输出:

       ID                 values_in                                  values_out
    0   1        [0.33, 0.91, 0.28]         [0.36, 0.5, 0.47, 0.98, 0.34, 0.37]
    1   2               [0.36, 0.5]  [0.33, 0.91, 0.28, 0.47, 0.98, 0.34, 0.37]
    2   3  [0.47, 0.98, 0.34, 0.37]               [0.33, 0.91, 0.28, 0.36, 0.5]
    
        Id  values
    0   1       12
    1   1       13
    2   2       14
    3   2       15
    4   2       12
    5   3       12
    

    我正在使用同一场景的另一个示例来演示如何做到这一点:

    ids=[1,1,2,2,2,3]
    values=[12,13,14,15,12,12]
    df = pd.DataFrame({'Id':ids,'values':values})
    df
    
    输出:

       ID                 values_in                                  values_out
    0   1        [0.33, 0.91, 0.28]         [0.36, 0.5, 0.47, 0.98, 0.34, 0.37]
    1   2               [0.36, 0.5]  [0.33, 0.91, 0.28, 0.47, 0.98, 0.34, 0.37]
    2   3  [0.47, 0.98, 0.34, 0.37]               [0.33, 0.91, 0.28, 0.36, 0.5]
    
        Id  values
    0   1       12
    1   1       13
    2   2       14
    3   2       15
    4   2       12
    5   3       12
    
    现在,您可以分别获取中的值和中的

    df2 = pd.DataFrame()
    for i in df["Id"].unique(): # Iterate through unique values of Ids
        in_list = list(df.loc[df['Id']==i, 'values']) # values_in
        out_list = list(df.loc[df['Id']!=i, 'values'])  #values_out
        df2 = df2.append([[i,in_list,out_list]]) #append each records
    df2.columns = ["ID","Values_in","Values_out"] #rename columns
    
    输出:

        ID      Values_in            Values_out
    0   1        [12, 13]      [14, 15, 12, 12]
    0   2    [14, 15, 12]          [12, 13, 12]
    0   3            [12]  [12, 13, 14, 15, 12]
    

    如果不需要重复的值,可以使用set而不是list来设置输入值和输出值

    使用自定义函数,并按
    ID
    中的值进行筛选:


    我尝试了所有的解决方案,但都不是很有效(循环太慢)

    我的解决方案是交叉连接并删除重复项

    df_-in=df.groupby('ID')['Value'])。应用(列表)。重置索引(name=“values_-in”)
    df_out=pd.merge(df,df,how=“交叉”)
    df_out=df_out.loc[df_[“ID_x”]!=df_[“ID_y”]”。groupby('ID_x')['Value_y']。应用(列表)。重置索引(name=“values_out”)
    final_df=pd.merge(df_in,df_out,on=“ID”,how=“full”)
    
    @jezrael这有点像黑客,但我试了一下;)什么是
    matmul
    ?@Steven矩阵乘法,可以与运算符@I have a error
    TypeError一起使用:当前不支持对象数组
    。这是因为我的分组键实际上是一个复合键吗?它出现在哪一行?我仍然在考虑条件
    df['Value'].isin(g['Value'])
    如果重复并且不幸的是您的答案失败了,那么工作正常
    {'ID':[1,1,1,2,2,3,3,3],'Value':[0.98,0.28,0.36,0.98,0.47,0.98,0.34,0.37]}
    @jezrael如果需要考虑重复,那么在这种情况下,只需删除
    isin
    就足够了。@ShubhamSharma感谢您的回答。对于复合密钥,您将如何执行相同的操作<代码>[“ID1”,“ID2”]
    而不仅仅是
    “ID”
    ?@Steven我想你可以在
    ID1
    ID2
    上使用
    groupby
    ,然后使用上面的代码。有些事情可能会奏效。。