我想根据第一列(“ MASTER”)中的字符串的主列表对数据框(3106行x 24列)进行排序,以便在存在匹配项的情况下对齐数据帧每一行中的字符串,并且如果不匹配,则为该单元格打印0。主列表在任何列中都包含所有可能的字符串,但并不是每个字符串都会出现在每一列中。
这篇SO帖子与我正在尝试做的非常接近:
Align DataFrames in pandas so that data matches in rows
我尝试使用这种方法,发现它只是根据主列中的顺序查看每个字符串是否匹配,但不会在整个列中搜索匹配项或进行任何重新排序。
new_data = data[data.apply(lambda x: x['MASTER'] == x, axis=1)]
这就是我要完成的数据处理。
之前
MASTER CENTRAL_NERVOUS NERVOUS_SYSTEM NEUROGENESIS
12AEX 9630013A20RIK 12AEX 2610301B20RIK
2610042L04RIK AARS 2610042L04RIK 9630013A20RIK
2610301B20RIK AATK 2610301B20RIK A830010M20RIK
2700046G09RIK ABCA2 2700046G09RIK AU040320
31BEX ABCB1B 31BEX AATK
38DLP ABCB6 7A6EX ABCA2
7A6EX ABL1 9630013A20RIK ABCC8
9630013A20RIK ABL2 97C2 ABI1
97C2 ABR A830010M20RIK ABI2
... ... ... ...
之后
MASTER CENTRAL_NERVOUS NERVOUS_SYSTEM NEUROGENESIS
12AEX 0 12AEX 0
2610042L04RIK 0 2610042L04RIK 0
2610301B20RIK 0 2610301B20RIK 2610301B20RIK
2700046G09RIK 0 2700046G09RIK 0
31BEX 0 31BEX 0
38DLP 0 0 0
7A6EX 0 7A6EX 0
9630013A20RIK 9630013A20RIK 9630013A20RIK 9630013A20RIK
97C2 0 97C2 0
我一直在尝试使用pandas / python来做到这一点,但将对带有awk / bash或R的解决方案开放。由于我一直停留在这一点上,所以任何提示/未来的方向都是值得的。
答案 0 :(得分:1)
我们可以在R中使用lapply
和match
df[-1] <- lapply(df[-1], function(x) x[match(df$MASTER, x)])
#If need to change to 0 or by default it is NA
df[is.na(df)] <- 0
# MASTER CENTRAL_NERVOUS NERVOUS_SYSTEM NEUROGENESIS
#1 12AEX 0 12AEX 0
#2 2610042L04RIK 0 2610042L04RIK 0
#3 2610301B20RIK 0 2610301B20RIK 2610301B20RIK
#4 2700046G09RIK 0 2700046G09RIK 0
#5 31BEX 0 31BEX 0
#6 38DLP 0 0 0
#7 7A6EX 0 7A6EX 0
#8 9630013A20RIK 9630013A20RIK 9630013A20RIK 9630013A20RIK
#9 97C2 0 97C2 0
并类似地使用dplyr
library(dplyr)
df %>% mutate_at(-1, ~.[match(MASTER, .)])
数据
如果要将值转换为0,请确保列是字符而不是因数。
df <- structure(list(MASTER = c("12AEX", "2610042L04RIK", "2610301B20RIK",
"2700046G09RIK", "31BEX", "38DLP", "7A6EX", "9630013A20RIK",
"97C2"), CENTRAL_NERVOUS = c("9630013A20RIK", "AARS", "AATK",
"ABCA2", "ABCB1B", "ABCB6", "ABL1", "ABL2", "ABR"), NERVOUS_SYSTEM = c("12AEX",
"2610042L04RIK", "2610301B20RIK", "2700046G09RIK", "31BEX", "7A6EX",
"9630013A20RIK", "97C2", "A830010M20RIK"), NEUROGENESIS = c("2610301B20RIK",
"9630013A20RIK", "A830010M20RIK", "AU040320", "AATK", "ABCA2",
"ABCC8", "ABI1", "ABI2")), class = "data.frame", row.names = c(NA, -9L))
答案 1 :(得分:1)
IIUC,您可以在熊猫中使用applymap
或apply
。我不确定您的示例中的排序顺序。
df[df.applymap(lambda x: x in df.MASTER.tolist())].fillna(0)
或
df[df.apply(lambda col: col.isin(df.MASTER))].fillna(0)
结果:
| | MASTER | CENTRAL_NERVOUS | NERVOUS_SYSTEM | NEUROGENESIS |
|---|---------------|-----------------|----------------|---------------|
| 0 | 12AEX | 9630013A20RIK | 12AEX | 2610301B20RIK |
| 1 | 2610042L04RIK | 0 | 2610042L04RIK | 9630013A20RIK |
| 2 | 2610301B20RIK | 0 | 2610301B20RIK | 0 |
| 3 | 2700046G09RIK | 0 | 2700046G09RIK | 0 |
| 4 | 31BEX | 0 | 31BEX | 0 |
| 5 | 38DLP | 0 | 7A6EX | 0 |
| 6 | 7A6EX | 0 | 9630013A20RIK | 0 |
| 7 | 9630013A20RIK | 0 | 97C2 | 0 |
| 8 | 97C2 | 0 | 0 | 0 |
如果您希望按MASTER
排序的行,请在下面使用,而不要使用apply
。
dfs = np.split(df,len(df.columns), axis=1)
dfs = [df.set_index(df.columns[0], drop=False) for df in dfs]
dfs[0].join(dfs[1:]).reset_index(drop=True).fillna(0)
结果:
| | MASTER | CENTRAL_NERVOUS | NERVOUS_SYSTEM | NEUROGENESIS |
|---|---------------|-----------------|----------------|---------------|
| 0 | 12AEX | 0 | 12AEX | 0 |
| 1 | 2610042L04RIK | 0 | 2610042L04RIK | 0 |
| 2 | 2610301B20RIK | 0 | 2610301B20RIK | 2610301B20RIK |
| 3 | 2700046G09RIK | 0 | 2700046G09RIK | 0 |
| 4 | 31BEX | 0 | 31BEX | 0 |
| 5 | 38DLP | 0 | 0 | 0 |
| 6 | 7A6EX | 0 | 7A6EX | 0 |
| 7 | 9630013A20RIK | 9630013A20RIK | 9630013A20RIK | 9630013A20RIK |
| 8 | 97C2 | 0 | 97C2 | 0 |