如何复制pandas DataFrame的行并周期性更改一列

4

我有一个类似于df的东西

pd.DataFrame([["A1"     "B1",      "C1", "P"],
              ["A2"     "B2",      "C2", "P"],
              ["A3"     "B3",      "C3", "P"]], columns=["col_a"  "col_b",   "col_c", "col_d"])


col_a  col_b   col_c col_d
A1     B1      C1    P
A2     B2      C2    P
A3     B3      C3    P
...

我需要的结果基本上是重复并确保每个唯一行出现在col_d中具有PQR扩展的列。
col_a  col_b   col_c col_d
A1     B1      C1    P
A1     B1      C1    Q
A1     B1      C1    R

A2     B2      C2    P
A2     B2      C2    Q
A2     B2      C2    R

A3     B3      C3    P
A3     B3      C3    Q
A3     B3      C3    R
...

目前我所拥有的只有:

new_df = pd.DataFrame(np.repeat(df.values, 3, axis=0), columns=df.columns)

这将导致这些值的重复,但 col_d 没有改变。

编辑:

现在我又遇到了另一个需求,即对于每个唯一的 col_a 和 col_b,我需要向 col_d 添加 "S"。

例如,会导致以下结果:

col_a  col_b   col_c col_d
A1     B1      C1    P
A1     B1      C1    Q
A1     B1      C1    R
A1     B1       T    S

A2     B2      C2    P
A2     B2      C2    Q
A2     B2      C2    R
A2     B2       T    S

非常感谢您的帮助!
3个回答

3
使用DataFrame.assignnumpy.tile,将值添加到列col_d中:
L = ['P','Q','R']
new_df = (pd.DataFrame(np.repeat(df.values, 3, axis=0), columns=df.columns)
           .assign(col_d = np.tile(L, len(df))))

print (new_df)
  col_acol_b col_c col_d
0       A1B1    C1     P
1       A1B1    C1     Q
2       A1B1    C1     R
3       A2B2    C2     P
4       A2B2    C2     Q
5       A2B2    C2     R
6       A3B3    C3     P
7       A3B3    C3     Q
8       A3B3    C3     R

另一个类似的想法是使用 DataFrame.loc 重复索引和重复行:

L = ['P','Q','R']
new_df = (df.loc[df.index.repeat(3)]
            .assign(col_d = np.tile(L, len(df)))
            .reset_index(drop=True))

print (new_df)
  col_acol_b col_c col_d
0       A1B1    C1     P
1       A1B1    C1     Q
2       A1B1    C1     R
3       A2B2    C2     P
4       A2B2    C2     Q
5       A2B2    C2     R
6       A3B3    C3     P
7       A3B3    C3     Q
8       A3B3    C3     R

编辑:

L = ['P','Q','R','S']
new_df = (pd.DataFrame(np.repeat(df.values, len(L), axis=0), columns=df.columns)
           .assign(col_d = np.tile(L, len(df)),
                   col_c = lambda x: x['col_c'].mask(x['col_d'].eq('S'), 'T')))

print (new_df)
   col_acol_b col_c col_d
0        A1B1    C1     P
1        A1B1    C1     Q
2        A1B1    C1     R
3        A1B1     T     S
4        A2B2    C2     P
5        A2B2    C2     Q
6        A2B2    C2     R
7        A2B2     T     S
8        A3B3    C3     P
9        A3B3    C3     Q
10       A3B3    C3     R
11       A3B3     T     S

太好了,它能正常工作! 现在我遇到了另一个需求,在每个唯一的col_a和col_b中,我需要将"S"添加到col_d中。 例如,结果如下所示:col_a col_b col_c col_d A1 B1 C1 P A1 B1 C1 Q A1 B1 C1 R A1 B1 T S A2 B2 C2 P A2 B2 C2 Q A2 B2 C2 R A2 B2 T S - DisplayedName
我把它添加到了问题中。 - DisplayedName
@DisplayedName - 你能检查一下编辑吗? - jezrael
先生,您是个天才。非常感谢!您在哪里学习了这样的pandas技能? - DisplayedName
1
@DisplayedName - 许多个小时的编码 ;) - jezrael

1

如果您已经有了第一个数据帧,您可以使用assignexplode

l= ['P','Q','R']
new_df = df.assign(col_d=[l]*len(df)).explode('col_d')

或者 merge 函数:

new_df = df.drop(columns='col_d').merge(pd.Series(l, name='col_d'), how='cross')

输出:

  col_acol_b col_c col_d
0       A1B1    C1     P
1       A1B1    C1     Q
2       A1B1    C1     R
3       A2B2    C2     P
4       A2B2    C2     Q
5       A2B2    C2     R
6       A3B3    C3     P
7       A3B3    C3     Q
8       A3B3    C3     R

1

您可以使用pyjanitor中的complete函数轻松生成组合:

# pip install pyjanitor
import pandas as pd
import janitor 

df.complete(['col_a', 'col_b', 'col_c'], {'col_d': ['P','Q','R']})

  col_a col_b col_c col_d
0    A1    B1    C1     P
1    A1    B1    C1     Q
2    A1    B1    C1     R
3    A2    B2    C2     P
4    A2    B2    C2     Q
5    A2    B2    C2     R
6    A3    B3    C3     P
7    A3    B3    C3     Q
8    A3    B3    C3     R

基本上,你正在将['col_a','col_b','col_c'] {'col_d':['P','Q','R']}组合; 使用字典可以让您向数据中引入新值。
对于需要引入S的情况,您可以分解步骤:
(df
.complete(['col_a', 'col_b'], {'col_d': ['P','Q','R', 'S']})
.assign(col_c = lambda df: np.where(df.col_d.eq('S'), 'T', df.col_c))
.ffill()
)

   col_a col_b col_c col_d
0     A1    B1    C1     P
1     A1    B1    C1     Q
2     A1    B1    C1     R
3     A1    B1     T     S
4     A2    B2    C2     P
5     A2    B2    C2     Q
6     A2    B2    C2     R
7     A2    B2     T     S
8     A3    B3    C3     P
9     A3    B3    C3     Q
10    A3    B3    C3     R
11    A3    B3     T     S

1
永远是个好看的管理员 ;) - mozway

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接