熊猫拆分列并创建元组列

时间:2020-06-03 04:26:33

标签: python pandas dataframe split tuples

我有一个如下数据框:

# df

colA     colB          colC

rqp      129            a   
pot      217;345        u
ghay     716            b
rbba     217;345        d
tary     612;811;760    a
kals     716            t

ColB(显示的两个组件中的任何一个)和ColC组合构成唯一的组合。 我想从该数据框中创建一个数据框,如下所示:

# newdf:

colAA      coLBB      

(129,a)    (a,rqp)
(217,u)    (u,pot)
(345,u)    (u,pot)
(716,b)    (b,ghay)
(217,d)    (d,rbba)
(345,d)    (d,rbba)
(612,a)    (a,tary)
(811,a)    (a,tary)
(760,a)    (a,tary)
(716,t)    (t,kals)

如果colB中只有一个元素,我尝试创建新列,但是无法获得如何使用分号分隔符以及如何创建元组列的方法。

如果ColB中没有分号,则可以使用

df['AA'] = list(zip(df[colB], df[colC]))
df['AB'] = list(zip(df[colC], df[colA]))

但是ColB中存在分号,我遇到了问题,如如何将字符串拆分为多个字符串并分配元组。 任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

使用Series.str.split围绕定界符colB拆分列;的字符串,然后使用DataFrame.explode将列colB的每个元素转换为一行,复制索引值。然后使用DataFrame.agg将所需的列沿tuple汇总为axis=1

df['colB'] = df['colB'].str.split(';')
df = df.explode('colB')
df['ColAA'] = df[['colB', 'colC']].agg(tuple, axis=1)
df['ColBB'] = df[['colC', 'colA']].agg(tuple, axis=1)
df = df[['ColAA', 'ColBB']].reset_index(drop=True)

结果:

# print(df)
     ColAA      ColBB
0  (129, a)   (a, rqp)
1  (217, u)   (u, pot)
2  (345, u)   (u, pot)
3  (716, b)  (b, ghay)
4  (217, d)  (d, rbba)
5  (345, d)  (d, rbba)
6  (612, a)  (a, tary)
7  (811, a)  (a, tary)
8  (760, a)  (a, tary)
9  (716, t)  (t, kals)

答案 1 :(得分:0)

您可以简单地将str.split()与扩展参数一起使用,以拆分列表并基于拆分获得新列。

df['colB'].str.split(pat=';',expand=True)

Read more here

答案 2 :(得分:0)

代码

def merge(row):
    return pd.Series({
            "colAA": (row.colB, row.colC),
            "colBB": (row.colC, row.colA),
        })

df['colB'] = df['colB'].str.split(';')
df = df.explode('colB')
newDf = df.apply(merge, axis=1).reset_index(drop=True)

说明

您可以split colB来获取值列表, 然后应用explode函数以获取多行

df['colB'] = df['colB'].str.split(';')
df = df.explode('colB')

# output
    colA    colB    colC
0   rqp 129 a
1   pot 217 u
1   pot 345 u
2   ghay    716 b
3   rbba    217 d

然后应用下面的合并功能来创建新的数据框

def merge(row):
    for b in row.colB.split(";"):
         return pd.Series({
            "colAA": (b, row.colC),
            "colBB": (row.colC, row.colA),

        })

然后在Df上应用此功能

newDf = df.apply(merge, axis=1).reset_index(drop=True)

# output
    colAA        colBB
0   (129, a)    (a, rqp)
1   (217, u)    (u, pot)
2   (345, u)    (u, pot)
3   (716, b)    (b, ghay)
4   (217, d)    (d, rbba)
5   (345, d)    (d, rbba)
6   (612, a)    (a, tary)
7   (811, a)    (a, tary)
8   (760, a)    (a, tary)
9   (716, t)    (t, kals)