pandas create new column based on values from other columns
我试过不同于其他问题的方法,但仍然找不到正确的答案。关键的一点是,如果这个人被算作拉美裔,他们就不能算作其他人。即使他们在另一个种族栏中有"1",他们仍然被算作拉美裔,而不是两个或两个以上的种族。同样,如果所有ERI列的总和大于1,则将它们算作两个或两个以上的种族,不能算作一个独特的种族(接受西班牙裔)。希望这是合理的。任何帮助都将不胜感激。
它几乎就像在每一行中执行for循环,如果每个记录满足一个条件,它们将被添加到一个列表中并从原始列表中删除。
根据下面的数据框架,我需要根据以下内容计算新列:
====================条件=========================
1 2 3 4 5 6 7 | IF [ERI_Hispanic] = 1 THEN RETURN"Hispanic" ELSE IF SUM([ERI_AmerInd_AKNatv] + [ERI_Asian] + [ERI_Black_Afr.Amer] + [ERI_HI_PacIsl] + [ERI_White]) > 1 THEN RETURN"Two or More" ELSE IF [ERI_AmerInd_AKNatv] = 1 THEN RETURN"A/I AK Native" ELSE IF [ERI_Asian] = 1 THEN RETURN"Asian" ELSE IF [ERI_Black_Afr.Amer] = 1 THEN RETURN"Black/AA" ELSE IF [ERI_HI_PacIsl] = 1 THEN RETURN"Haw/Pac Isl." ELSE IF [ERI_White] = 1 THEN RETURN"White" |
备注:如果拉美裔的ERI标志为真(1),则员工被归类为"拉美裔"。
注释:如果超过1个非西班牙裔ERI标志为真,则返回"两个或更多"
===============数据帧=================
1 2 3 4 5 6 7 8 9 10 11 | lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined 0 MOST JEFF E 0 0 0 0 0 1 White 1 CRUISE TOM E 0 0 0 1 0 0 White 2 DEPP JOHNNY 0 0 0 0 0 1 Unknown 3 DICAP LEO 0 0 0 0 0 1 Unknown 4 BRANDO MARLON E 0 0 0 0 0 0 White 5 HANKS TOM 0 0 0 0 0 1 Unknown 6 DENIRO ROBERT E 0 1 0 0 0 1 White 7 PACINO AL E 0 0 0 0 0 1 White 8 WILLIAMS ROBIN E 0 0 1 0 0 0 White 9 EASTWOOD CLINT E 0 0 0 0 0 1 White |
好的,这有两个步骤-第一步是编写一个函数来完成您想要的转换-我已经根据您的伪代码将一个示例放在一起:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def label_race (row): if row['eri_hispanic'] == 1 : return 'Hispanic' if row['eri_afr_amer'] + row['eri_asian'] + row['eri_hawaiian'] + row['eri_nat_amer'] + row['eri_white'] > 1 : return 'Two Or More' if row['eri_nat_amer'] == 1 : return 'A/I AK Native' if row['eri_asian'] == 1: return 'Asian' if row['eri_afr_amer'] == 1: return 'Black/AA' if row['eri_hawaiian'] == 1: return 'Haw/Pac Isl.' if row['eri_white'] == 1: return 'White' return 'Other' |
您可能想讨论一下这个问题,但它似乎做到了这一点——注意,进入函数的参数被认为是一个标有"row"的序列对象。
接下来,使用熊猫中的应用功能来应用该功能-例如
1 | df.apply (lambda row: label_race(row), axis=1) |
注意axis=1说明符,这意味着应用程序是在一行而不是列级别完成的。结果如下:
1 2 3 4 5 6 7 8 9 10 | 0 White 1 Hispanic 2 White 3 White 4 Other 5 White 6 Two Or More 7 White 8 Haw/Pac Isl. 9 White |
如果您对这些结果满意,那么再次运行它,将结果保存到原始数据框的新列中。
1 | df['race_label'] = df.apply (lambda row: label_race(row), axis=1) |
结果数据框如下(向右滚动查看新列):
1 2 3 4 5 6 7 8 9 10 11 | lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined race_label 0 MOST JEFF E 0 0 0 0 0 1 White White 1 CRUISE TOM E 0 0 0 1 0 0 White Hispanic 2 DEPP JOHNNY NaN 0 0 0 0 0 1 Unknown White 3 DICAP LEO NaN 0 0 0 0 0 1 Unknown White 4 BRANDO MARLON E 0 0 0 0 0 0 White Other 5 HANKS TOM NaN 0 0 0 0 0 1 Unknown White 6 DENIRO ROBERT E 0 1 0 0 0 1 White Two Or More 7 PACINO AL E 0 0 0 0 0 1 White White 8 WILLIAMS ROBIN E 0 0 1 0 0 0 White Haw/Pac Isl. 9 EASTWOOD CLINT E 0 0 0 0 0 1 White White |
因为这是"其他人的熊猫新专栏"的第一个谷歌结果,下面是一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import pandas as pd # make a simple dataframe df = pd.DataFrame({'a':[1,2], 'b':[3,4]}) df # a b # 0 1 3 # 1 2 4 # create an unattached column with an index df.apply(lambda row: row.a + row.b, axis=1) # 0 4 # 1 6 # do same but attach it to the dataframe df['c'] = df.apply(lambda row: row.a + row.b, axis=1) df # a b c # 0 1 3 4 # 1 2 4 6 |
如果你得到了
1 2 3 | fn = lambda row: row.a + row.b # define a function for the new column col = df.apply(fn, axis=1) # get column data with an index df = df.assign(c=col.values) # assign values to column 'c' |
来源:https://stackoverflow.com/a/12555510/243392
如果列名包含空格,则可以使用如下语法:
1 | df = df.assign(**{'some column name': col.values}) |
这是申请和分配的文档。
1 | df['race_label'] = df.apply(label_race, axis=1) |
不需要生成lambda函数来传递函数。
上述答案是完全正确的,但存在矢量化的解决方案,形式为
首先,定义条件:
1 2 3 4 5 6 7 8 9 | conditions = [ df['eri_hispanic'] == 1, df[['eri_afr_amer', 'eri_asian', 'eri_hawaiian', 'eri_nat_amer', 'eri_white']].sum(1).gt(1), df['eri_nat_amer'] == 1, df['eri_asian'] == 1, df['eri_afr_amer'] == 1, df['eri_hawaiian'] == 1, df['eri_white'] == 1, ] |
现在,定义相应的输出:
1 2 3 | outputs = [ 'Hispanic', 'Two Or More', 'A/I AK Native', 'Asian', 'Black/AA', 'Haw/Pac Isl.', 'White' ] |
最后,使用
1 2 | res = np.select(conditions, outputs, 'Other') pd.Series(res) |
1 2 3 4 5 6 7 8 9 10 11 | 0 White 1 Hispanic 2 White 3 White 4 Other 5 White 6 Two Or More 7 White 8 Haw/Pac Isl. 9 White dtype: object |
为什么要在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | df = pd.concat([df]*1000) In [42]: %timeit df.apply(lambda row: label_race(row), axis=1) 1.07 s ± 4.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) In [44]: %%timeit ...: conditions = [ ...: df['eri_hispanic'] == 1, ...: df[['eri_afr_amer', 'eri_asian', 'eri_hawaiian', 'eri_nat_amer', 'eri_white']].sum(1).gt(1), ...: df['eri_nat_amer'] == 1, ...: df['eri_asian'] == 1, ...: df['eri_afr_amer'] == 1, ...: df['eri_hawaiian'] == 1, ...: df['eri_white'] == 1, ...: ] ...: ...: outputs = [ ...: 'Hispanic', 'Two Or More', 'A/I AK Native', 'Asian', 'Black/AA', 'Haw/Pac Isl.', 'White' ...: ] ...: ...: np.select(conditions, outputs, 'Other') ...: ...: 3.09 ms ± 17 μs per loop (mean ± std. dev. of 7 runs, 100 loops each) |
使用