在其他列为NaN的情况下,填写相同数量的字符

Erf*_*fan 8 python explode pandas unnest

我有以下虚拟数据框:

df = pd.DataFrame({'Col1':['a,b,c,d', 'e,f,g,h', 'i,j,k,l,m'],
                   'Col2':['aa~bb~cc~dd', np.NaN, 'ii~jj~kk~ll~mm']})

        Col1            Col2
0    a,b,c,d     aa~bb~cc~dd
1    e,f,g,h             NaN
2  i,j,k,l,m  ii~jj~kk~ll~mm
Run Code Online (Sandbox Code Playgroud)

真实数据集具有形状500000, 90

我需要将这些值取消嵌套到行中,并且explode为此使用了新方法,该方法工作正常。

问题是NaN,这些将导致后面的长度不相等explode,因此我需要填充与填充值相同数量的定界符。在这种情况下,~~~由于第1行具有三个逗号。


预期产量

        Col1            Col2
0    a,b,c,d     aa~bb~cc~dd
1    e,f,g,h             ~~~
2  i,j,k,l,m  ii~jj~kk~ll~mm
Run Code Online (Sandbox Code Playgroud)

尝试1

df['Col2'].fillna(df['Col1'].str.count(',')*'~')
Run Code Online (Sandbox Code Playgroud)

尝试2:

np.where(df['Col2'].isna(), df['Col1'].str.count(',')*'~', df['Col2'])
Run Code Online (Sandbox Code Playgroud)

这可行,但是我觉得有一个更简单的方法:

characters = df['Col1'].str.replace('\w', '').str.replace(',', '~')
df['Col2'] = df['Col2'].fillna(characters)

print(df)

        Col1            Col2
0    a,b,c,d     aa~bb~cc~dd
1    e,f,g,h             ~~~
2  i,j,k,l,m  ii~jj~kk~ll~mm

d1 = df.assign(Col1=df['Col1'].str.split(',')).explode('Col1')[['Col1']]
d2 = df.assign(Col2=df['Col2'].str.split('~')).explode('Col2')[['Col2']]

final = pd.concat([d1,d2], axis=1)
print(final)

  Col1 Col2
0    a   aa
0    b   bb
0    c   cc
0    d   dd
1    e     
1    f     
1    g     
1    h     
2    i   ii
2    j   jj
2    k   kk
2    l   ll
2    m   mm
Run Code Online (Sandbox Code Playgroud)

问题:是否有更简单,更通用的方法?还是我的方法没问题。

piR*_*red 4

pd.concat

delims = {'Col1': ',', 'Col2': '~'}
pd.concat({
    k: df[k].str.split(delims[k], expand=True)
    for k in df}, axis=1
).stack()

    Col1 Col2
0 0    a   aa
  1    b   bb
  2    c   cc
  3    d   dd
1 0    e  NaN
  1    f  NaN
  2    g  NaN
  3    h  NaN
2 0    i   ii
  1    j   jj
  2    k   kk
  3    l   ll
  4    m   mm
Run Code Online (Sandbox Code Playgroud)

这在 中的列上循环df。循环字典中的键可能更明智delims

delims = {'Col1': ',', 'Col2': '~'}
pd.concat({
    k: df[k].str.split(delims[k], expand=True)
    for k in delims}, axis=1
).stack()
Run Code Online (Sandbox Code Playgroud)

一样的东西,不一样的样子

delims = {'Col1': ',', 'Col2': '~'}
def f(c): return df[c].str.split(delims[c], expand=True)
pd.concat(map(f, delims), keys=delims, axis=1).stack()
Run Code Online (Sandbox Code Playgroud)