我遇到了一个问题,必须将一行拆分为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
决定列的哪一部分保留为标头。完整的功能简单地组合并引入了基于Date
、Random1
和Random2
的by
分组的新行