创建一个新列提取值等于列名的值

Posted

技术标签:

【中文标题】创建一个新列提取值等于列名的值【英文标题】:Create a new column pulls in values where a value equals a column name 【发布时间】:2020-01-15 13:21:55 【问题描述】:

抱歉,如果答案已经存在,我是 python 新手,我找不到答案。

也就是说,我正在使用一个 pandas 数据框,该数据框具有一个聚合总和和各种其他列,这些列分解了总和的来源。

我想提出一个代码来创建一个新列,其中一个列名的值等于另一个列名的值,如果它不等于任何列 0,并迭代每一行。

例如,我有以下简单的表(我的数据集要大得多,所以我需要一些东西来迭代几行):

  Value  Aggregate  A  B  C
0     A          5  4  1  0
1     B          4  3  1  0
2     C         12  1  5  6
3     D          8  4  3  1

并希望获得以下信息:

Value Aggregate A   B   C   New Column
   A    5       4   1   0      4
   B    4       3   1   0      1
   C    12      1   5   6      6
   D    8       4   3   1      0

【问题讨论】:

能否请您以可以复制和粘贴的方式提供您的示例数据? 你不应该恢复我的编辑。文本示例数据比图片更有帮助。 很抱歉,这是我第一次使用 Overstack ......只是习惯了它 " 一个新列,其中一个列名的值等于另一个列的字段值" 你能举个例子并详细说明吗? 所以我有一列“value”由各种字符串(“A”、“B”、“C”等)组成,另一列“Aggregate”是总和其余列(A,B,C)中的整数......我想做的是提出一个代码,它遍历“值”列的每一行,如果它与列的名称匹配(A, B,C)然后我希望它插入该值,如果没有,则放入 0。 【参考方案1】:

这是广播的一种方法:

cols = df.columns[-3:].values
mask = df['Value'].values[:,None] == cols
(df[cols]*mask).sum(1)

输出:

0    4
1    1
2    6
3    0
dtype: int64

【讨论】:

@anky_91 我做了两次,但它被还原了两次 :)【参考方案2】:

lookup 但处理不存在的列:

m = df.Value.isin(df.columns)
df.loc[m, 'New Col'] = df.lookup(df[m].index, df[m].Value)
df['New Col'] = df['New Col'].fillna(0, downcast='int64')

  Value  Aggregate  A  B  C  New Col
0     A          5  4  1  0        4
1     B          4  3  1  0        1
2     C         12  1  5  6        6
3     D          8  4  3  1        0

【讨论】:

谢谢!如果行标签和列的大小不同,您知道如何使用它吗?希望在更大的数据集上执行此操作并收到此错误...“ValueError:行标签必须与列标签具有相同的大小” @RyanO'Brien 这个错误有点误导。您传递给lookup 的两个参数是row_labelscol_labels,在这种情况下它们分别是df[m].indexdf[m].Value。这需要是相同的形状,而不是 DataFrame 中的实际列或行。您是否可能忘记在代码中使用[m] 分割其中一个?【参考方案3】:

这是使用“堆叠”的另一种方式。

创建数据框并确保 Value 是索引:

df = pd.DataFrame([['A',5,4,1,0],['B',4,3,1,0],['C',12,1,5,6],['D',8,4,3,1]], columns=['Value','Aggregate Leads', 'A','B','C'])
df.set_index('Value', inplace=True)

df
Out[154]: 
       Aggregate Leads  A  B  C
Value                          
A                    5  4  1  0
B                    4  3  1  0
C                   12  1  5  6
D                    8  4  3  1

堆叠列并重置索引:

temp = df[['A','B','C']].stack().reset_index()

比较索引和列名以获取值并重新加入数据框:

df.join(temp[temp.Value==temp.level_1].set_index('Value').iloc[:,-1]).fillna(0)

Out[156]: 
       Aggregate Leads  A  B  C    0
Value                               
A                    5  4  1  0  4.0
B                    4  3  1  0  1.0
C                   12  1  5  6  6.0
D                    8  4  3  1  0.0

【讨论】:

以上是关于创建一个新列提取值等于列名的值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle 中的每个破折号后划分字符并根据提取的值创建新列?

根据其他列名和值创建新列

如何使用行的值作为新列重新格式化数据集?

将数据框中的值列表附加到新列[重复]

如何创建更新查询以将存储为文本的 xml 值提取到新列中

Python如何在pandas数据框中提取[]括号内的指定字符串并创建一个具有布尔值的新列