排序/对齐数据框列,以使行字符串值与主列表列匹配,如果列中不匹配则打印0

时间:2019-10-11 01:32:05

标签: python r pandas dataframe

我想根据第一列(“ 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的解决方案开放。由于我一直停留在这一点上,所以任何提示/未来的方向都是值得的。

2 个答案:

答案 0 :(得分:1)

我们可以在R中使用lapplymatch

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,您可以在熊猫中使用applymapapply。我不确定您的示例中的排序顺序。

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             |