pandas 如何在列中的第N个字符处拆分DataFrame行?

gg0vcinb  于 2023-09-29  发布在  其他
关注(0)|答案(6)|浏览(97)

我遇到过这样一种情况,在一列中,我可能有0、2、4或6个字符串,我需要将它们扩展为1、2或3行,如下所示:
电流
| 员工|工资等级|
| --|--|
| 约翰|7A5B|
| 凯西||
| 汤姆|9A9B4C|
期望
| 员工|工资等级|
| --|--|
| 约翰|7A|
| 约翰|5B|
| 凯西||
| 汤姆|9A|
| 汤姆|9B|
| 汤姆|4C|
我已经尝试了.split()和.explode(),但是在将每个字符串分成两个字符的组时遇到了一些问题

x6492ojm

x6492ojm1#

extractall的可能解决方案:

N = 2 # N'th character

out = (
    df[["Employee"]].join(
        df["Pay Grade"].str.extractall(r"(.{%s})" % N)[0]
        .rename("Pay Grade").droplevel(1)
    )
)

输出量:

print(out)

  Employee Pay Grade
0     John        7A
0     John        5B
1    Kathy       NaN
2      Tom        9A
2      Tom        9B
2      Tom        4C
ltqd579y

ltqd579y3#

您可以使用apply方法分隔字符串,并将值拆分到新行中:

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {
        "Employee": ["Jhon", "Kathy", "Tom"],
        "Pay Grade": ["7A5B", np.nan, "9A9B4C"]
    }
)
df["Pay Grade"].fillna("", inplace=True)

df["Pay Grade"] = df["Pay Grade"].apply(
    lambda value: '|'.join([value[i:i+2] for i in range(0, len(value), 2)])
)

df = df.join(
    df.pop("Pay Grade").str.extractall(r"([^|]+)").droplevel(1)[0].rename("Pay Grade")
).reset_index(drop=True)
goqiplq2

goqiplq24#

你很接近了我认为split是这里坚韧的部分。itertools pairwise recipe可以很好地处理explode

def pairs(x: str):
    it = iter(x)
    vals = []

    while True:
        a, b = next(it, ''), next(it, '')
        if not all((a, b)):
            break
        vals.append(''.join((a, b)))

    if a:
        vals.append(a)
    return vals

df['Pay Grade'].apply(pairs).explode()
n1bvdmb6

n1bvdmb65#

另一个解决方案:

import re

df = (
    df.assign(**{"Pay Grade": df["Pay Grade"].apply(lambda x: re.findall(r"..", x))})
    .explode("Pay Grade")
    .fillna("")
)
print(df)

图纸:

Employee Pay Grade
0     John        7A
0     John        5B
1    Kathy          
2      Tom        9A
2      Tom        9B
2      Tom        4C

或:无re

df["Pay Grade"] = df["Pay Grade"].str.extractall(r"(..)").groupby(level=0).agg(list)
print(df.explode("Pay Grade").fillna(""))
g52tjvyc

g52tjvyc6#

您可以使用wrap from textwrapPay Grade数据分割为2个字符块,分解这些值,然后将join返回到原始df:

import textwrap

out = (df
    .drop('Pay Grade', axis=1)
    .join(df['Pay Grade']
          .apply(textwrap.wrap, args=[2])
          .explode()
    )
    .fillna('')
    .reset_index(drop=True)
)

示例数据的输出:

Employee  Pay Grade
0     John         7A
1     John         5B
2    Kathy
3      Tom         9A
4      Tom         9B
5      Tom         4C

相关问题