将单行拆分为多个唯一的行Pandas排列



我遇到了一个问题,必须将一行拆分为8个行的组合。

示例I有8列——前6列属于硬币的每个面。以及最后两个任意伪列。如下所示(这是旧的df(

Date, Coin1_Face_1, Coin1_Face_2, Coin2_Face_1, Coin2_Face_2, Coin3_Face_1, Coin3_Face_2, Random1, Random2
1-Jan   H   T   H   T   H   T   X   Y
2-Jan   P   Q   P   Q   P   Q   A   B

我想减少列的数量,但增加行的数量,如下所示(这应该是new_df(:

Date, Coin_1, Coin_2, Coin_3, Random1, Random2
1-Jan   H   H   H   X   Y
1-Jan   H   H   T   X   Y
1-Jan   H   T   H   X   Y
1-Jan   H   T   T   X   Y
1-Jan   T   H   H   X   Y
1-Jan   T   H   T   X   Y
1-Jan   T   T   H   X   Y
1-Jan   T   T   T   X   Y
2-Jan   P   P   P   A   B
2-Jan   P   P   Q   A   B
2-Jan   P   Q   P   A   B
2-Jan   P   Q   Q   A   B
2-Jan   Q   P   P   A   B
2-Jan   Q   P   Q   A   B
2-Jan   Q   Q   P   A   B
2-Jan   Q   Q   Q   A   B

有人能帮忙吗。

尝试使用pd.wide_to_long,但我不确定您的行扩展,您的预期输出中必须有多行或少行。请解释如何扩展。

pd.wide_to_long(df,['Coin1', 'Coin2', 'Coin3'], ['Date', 'Random1', 'Random2'], 'j', '_', '.*').reset_index()

输出:

|    | Date   | Random1   | Random2   | j      | Coin1   | Coin2   | Coin3   |
|---:|:-------|:----------|:----------|:-------|:--------|:--------|:--------|
|  0 | 1-Jan  | X         | Y         | Face_1 | H       | H       | H       |
|  1 | 1-Jan  | X         | Y         | Face_2 | T       | T       | T       |
|  2 | 2-Jan  | A         | B         | Face_1 | P       | P       | P       |
|  3 | 2-Jan  | A         | B         | Face_2 | Q       | Q       | Q       |

尝试:

from itertools import combinations
df_m = pd.wide_to_long(df,['Coin1', 'Coin2', 'Coin3'], ['Date', 'Random1', 'Random2'], 'j', '_', '.*')
def f(g):
g = g.reset_index(level=3, drop=True)
indx = g.index.drop_duplicates()
data = list(combinations(g.to_numpy().flatten('F'), 3))
return (pd.DataFrame(data, 
columns=['Coin1', 'Coin2', 'Coin3'], 
index =indx.repeat(len(data)))
.drop_duplicates())

df_out = df_m.groupby(level=[0,1,2], as_index=False).apply(f).reset_index().drop('level_0', axis=1)  
print(df_out)

输出:

Date Random1 Random2 Coin1 Coin2 Coin3
0   1-Jan       X       Y     H     T     H
1   1-Jan       X       Y     H     T     T
2   1-Jan       X       Y     H     H     T
3   1-Jan       X       Y     H     H     H
4   1-Jan       X       Y     T     H     T
5   1-Jan       X       Y     T     H     H
6   1-Jan       X       Y     T     T     H
7   1-Jan       X       Y     T     T     T
8   2-Jan       A       B     P     Q     P
9   2-Jan       A       B     P     Q     Q
10  2-Jan       A       B     P     P     Q
11  2-Jan       A       B     P     P     P
12  2-Jan       A       B     Q     P     Q
13  2-Jan       A       B     Q     P     P
14  2-Jan       A       B     Q     Q     P
15  2-Jan       A       B     Q     Q     Q

pijanitor的pivot_langer和complete的组合可以帮助进行整形和行生成;pivot_langer转换为长格式,而complete引入了缺失的行:

# pip install pyjanitor
import pandas as pd
import janitor
(df
.pivot_longer(
column_names = "Coin*", 
names_to = ".value", 
names_pattern = "([A-Za-z]+d)_*", 
sort_by_appearance=True)
.complete(
'Coin1','Coin2','Coin3', 
by = ['Date', 'Random1', 'Random2'])
)
Date Random1 Random2 Coin1 Coin2 Coin3
0   1-Jan       X       Y     H     H     H
1   1-Jan       X       Y     H     H     T
2   1-Jan       X       Y     H     T     H
3   1-Jan       X       Y     H     T     T
4   1-Jan       X       Y     T     H     H
5   1-Jan       X       Y     T     H     T
6   1-Jan       X       Y     T     T     H
7   1-Jan       X       Y     T     T     T
8   2-Jan       A       B     P     P     P
9   2-Jan       A       B     P     P     Q
10  2-Jan       A       B     P     Q     P
11  2-Jan       A       B     P     Q     Q
12  2-Jan       A       B     Q     P     P
13  2-Jan       A       B     Q     P     Q
14  2-Jan       A       B     Q     Q     P
15  2-Jan       A       B     Q     Q     Q

pivot_langer中的.value决定列的哪一部分保留为标头。完整的功能简单地组合并引入了基于DateRandom1Random2by分组的新行

最新更新