Pandas stack() 如果列具有特定值
Pandas stack() if columns have a specific value
我正在尝试根据 ID 列堆叠此 table,但仅考虑值为 1 而不是 0 的列 [A-D]。
当前 df:
ID
A
B
C
D
1
1
0
0
1
3
0
1
0
1
7
1
0
1
1
8
1
0
0
0
我想要的:
ID
LETTER
1
A
1
D
3
B
3
D
7
A
7
C
7
D
8
A
以下代码有效,但我需要一个更有效的解决方案,因为我有一个 93434 行 x 12377 列的 df。
stacked_df = df.set_index('ID').stack().reset_index(name='has_letter').rename(columns={'level_1':'LETTER'})
stacked_df = stacked_df[stacked_df['has_letter']==1].reset_index(drop=True)
stacked_df.drop(['has_letter'], axis=1, inplace=True)
尝试:
print(
df.set_index("ID")
.apply(lambda x: x.index[x == 1], axis=1)
.reset_index()
.explode(0)
.rename(columns={0: "LETTERS"})
)
打印:
ID LETTERS
0 1 A
0 1 D
1 3 B
1 3 D
2 7 A
2 7 C
2 7 D
3 8 A
或者:
x = df.set_index("ID").stack()
print(
x[x == 1]
.reset_index()
.drop(columns=0)
.rename(columns={"level_1": "LETTER"})
)
打印:
ID LETTER
0 1 A
1 1 D
2 3 B
3 3 D
4 7 A
5 7 C
6 7 D
7 8 A
试试这个:
(df.set_index('ID').dot(df.columns[1:]) # use inner product of column names and values
.apply(list) # separate each letter
.explode() # explode each list
.reset_index(name='LETTER') # reset index for df
)
输出:
ID LETTER
0 1 A
1 1 D
2 3 B
3 3 D
4 7 A
5 7 C
6 7 D
7 8 A
您可以屏蔽非 1 值和 stack
以移除 NaN:
df2 = df.rename_axis(columns='LETTERS').set_index('ID')
stacked_df = (df2.where(df2.eq(1)).stack()
.reset_index().iloc[:,:2]
)
输出:
ID LETTERS
0 1 A
1 1 D
2 3 B
3 3 D
4 7 A
5 7 C
6 7 D
7 8 A
我正在尝试根据 ID 列堆叠此 table,但仅考虑值为 1 而不是 0 的列 [A-D]。
当前 df:
ID | A | B | C | D |
---|---|---|---|---|
1 | 1 | 0 | 0 | 1 |
3 | 0 | 1 | 0 | 1 |
7 | 1 | 0 | 1 | 1 |
8 | 1 | 0 | 0 | 0 |
我想要的:
ID | LETTER |
---|---|
1 | A |
1 | D |
3 | B |
3 | D |
7 | A |
7 | C |
7 | D |
8 | A |
以下代码有效,但我需要一个更有效的解决方案,因为我有一个 93434 行 x 12377 列的 df。
stacked_df = df.set_index('ID').stack().reset_index(name='has_letter').rename(columns={'level_1':'LETTER'})
stacked_df = stacked_df[stacked_df['has_letter']==1].reset_index(drop=True)
stacked_df.drop(['has_letter'], axis=1, inplace=True)
尝试:
print(
df.set_index("ID")
.apply(lambda x: x.index[x == 1], axis=1)
.reset_index()
.explode(0)
.rename(columns={0: "LETTERS"})
)
打印:
ID LETTERS
0 1 A
0 1 D
1 3 B
1 3 D
2 7 A
2 7 C
2 7 D
3 8 A
或者:
x = df.set_index("ID").stack()
print(
x[x == 1]
.reset_index()
.drop(columns=0)
.rename(columns={"level_1": "LETTER"})
)
打印:
ID LETTER
0 1 A
1 1 D
2 3 B
3 3 D
4 7 A
5 7 C
6 7 D
7 8 A
试试这个:
(df.set_index('ID').dot(df.columns[1:]) # use inner product of column names and values
.apply(list) # separate each letter
.explode() # explode each list
.reset_index(name='LETTER') # reset index for df
)
输出:
ID LETTER
0 1 A
1 1 D
2 3 B
3 3 D
4 7 A
5 7 C
6 7 D
7 8 A
您可以屏蔽非 1 值和 stack
以移除 NaN:
df2 = df.rename_axis(columns='LETTERS').set_index('ID')
stacked_df = (df2.where(df2.eq(1)).stack()
.reset_index().iloc[:,:2]
)
输出:
ID LETTERS
0 1 A
1 1 D
2 3 B
3 3 D
4 7 A
5 7 C
6 7 D
7 8 A