使用另一个具有不同列大小的数据框将新列添加到multiIndex数据框

时间:2020-04-12 11:44:41

标签: python pandas dataframe lambda

我有以下multiIndex数据框:

df= 
        id/uniqueID       var1    var2    var3   
        5171/0            10.0    2.8     0.0   
        5171/1            40.9    2.5     3.4   
        5171/2            60.7    3.1     5.2   
        ...
        5171/57           0.5     1.3     5.1   
        4567/0            1.5     2.0     1.0   
        4567/1            4.4     2.0     1.3   
        4567/2            6.3     3.0     1.5   
        ...
        4567/57           0.7     1.4     1.6   
       ... 
        9584/0            0.3     2.6     0.0   
        9584/1            0.5     1.2     8.3   
        9584/2            0.7     3.0     5.6   
        ...
        9584/57           0.7     1.3     0.1   

indexes_df= 
        id              labeled_idxs
        5171            [0,1,3,6,49,50]
        4567            [45,46,47,56,57]
        9584            [21]
        ...

我需要使用df1True添加一个新的二进制列,作为第二个数据帧indexes_df中标记的索引,如下所示:

df= 
        id/uniqueID       var1    var2    var3    labels
        5171/0            10.0    2.8     0.0       1
        5171/1            40.9    2.5     3.4       1
        5171/2            60.7    3.1     5.2       0
        ...
        5171/57           0.5     1.3     5.1       0
        4567/0            1.5     2.0     1.0       0
        4567/1            4.4     2.0     1.3       0   
        4567/2            6.3     3.0     1.5       0   
        ...
        4567/56           0.4     0.4     1.3       1
        4567/57           0.7     1.4     1.6       1   
       ... 
        9584/0            0.3     2.6     0.0       0   
        9584/1            0.5     1.2     8.3       0   
        9584/2            0.7     3.0     5.6       0   
        ...
        9584/21           2.7     0.0     0.6       1
        ...
        9584/57           0.7     1.3     0.1       0  

我尝试使用以下代码和类似方法进行操作,但它们均因SyntaxError而失败:

df['labes'] = indexes_df['labeled_idxs'].apply(lambda x: [i>0 ? 1 : 0 for i in x]))

如何获得所需的结果?

3 个答案:

答案 0 :(得分:1)

三元运算符在Python中不可用。但是,您可以使用类似的方法:

df['labes'] = indexes_df['labeled_idxs'].apply(lambda x: [1 if i > 0 else 0 for i in x]))

答案 1 :(得分:1)

您是正确的一半。解决方案是在列表理解中使用lambda,但是您有一些错误。 Python不使用?和:,所以您必须这样做:

df['labes'] = indexes_df['labeled_idxs'].apply(lambda x: [(1 if i>0 else 0) for i in x]))

答案 2 :(得分:1)

您的解决方案是有问题的,因为如果正确的apply部分(如另一个答案)仍然存在问题,则是

df['labes'] = indexes_df['labeled_idxs']

因为此处用于处理需要labeled_idxs,就像df DataFrame中的另一列或indexes_df的索引一样,必须与df相同。如果不是,则只有两个DataFrame中的索引值相同时,才为行设置值。


最好使用纯大熊猫解决方案-首先在DataFrame.explode列中将列表填充为行并转换为字符串:

indexes_df = indexes_df.explode('labeled_idxs')
print (indexes_df)
     labeled_idxs
id               
4567           45
4567           46
4567           47
4567           56
4567           57
          ...
5171            3
5171            6
5171           49
5171           50
9584           21

[62 rows x 1 columns]

更新:由于df是一个multiIndex数据框,因此以下内容应该有效

indexes_df = indexes_df.explode('labeled_idxs').astype(int)
indexes_df['labels'] = 1
indexes_df.set_index('labeled_idxs', append=True, inplace=True)
df['labels'] = 0  
df.loc[indexes_df.index, indexes_df.columns] = indexes_df

旧答案:

然后将indexDataFrame的列连接到Series,如下所示:

s = indexes_df.index.astype(str) + '/' + indexes_df['labeled_idxs'].astype(str)
print (s)
id
4567    4567/45
4567    4567/46
4567    4567/47
4567    4567/56
4567    4567/57

5171     5171/3
5171     5171/6
5171    5171/49
5171    5171/50
9584    9584/21
Length: 62, dtype: object

最后将Index.isinid/uniqueID列与具有布尔布尔值掩码的整数进行比较:

df['labes'] = df.index.isin(s).astype(int)
print (df)
             var1  var2  var3  labes
id/uniqueID                         
5171/0       10.0   2.8   0.0      1
5171/1       40.9   2.5   3.4      1
5171/2       60.7   3.1   5.2      0
5171/57       0.5   1.3   5.1      0
4567/0        1.5   2.0   1.0      0
4567/1        4.4   2.0   1.3      0
4567/2        6.3   3.0   1.5      0
4567/57       0.7   1.4   1.6      1
9584/0        0.3   2.6   0.0      0
9584/1        0.5   1.2   8.3      0
9584/2        0.7   3.0   5.6      0
9584/57       0.7   1.3   0.1      0