regex Pandas Column使用Conditional拆分一行并创建一个单独的列

au9on6nz  于 2023-10-22  发布在  其他
关注(0)|答案(3)|浏览(92)

这道题似乎不难,但不知怎么的我就是做不出来。我的问题如下。我有一句话要说:

dfin 

           A      B     C
           a      1     198q24
           a      2     128q6
           a      6     1456
           b      7     67q22
           b      1     56
           c      3     451q2
           d      11    1q789

所以现在我想做的是如下,每当脚本遇到'q'时,它将拆分值并创建一个单独的列,其中的值从'q'开始。q之前的部分将保留在原始列中(或者可以创建一个新列)。所以我的期望输出应该如下:

dfout 

           A      B     C        D
           a      1     198     q24
           a      2     128     q6
           a      6     1456
           b      7     67      q22
           b      1     56
           c      3     451     q2
           d      11    1       q789

所以我到目前为止所做的尝试如下:

dfout = dfin.replace('\q\d*', '', regex=True)

它创建了一个没有q的列,但是我不能创建列D,也不能按预期工作。
任何帮助/想法将帮助和赞赏。

qv7cva1a

qv7cva1a1#

import pandas as pd

def get_input() -> pd.DataFrame:
    csv_text = """
         a      1     198q24
         a      2     128q6
         a      6     1456
         b      7     67q22
         b      1     56
         c      3     451q2
         d      11    1q789
         """.strip()
    return pd.DataFrame(map(str.split, csv_text.splitlines()), columns=["a", "b", "c"])

def split_on_q(df_in: pd.DataFrame) -> pd.DataFrame:
    df = df_in.c.str.split("q", expand=True)
    df_out = df_in.copy()
    df_out["c"] = df[0]
    df_out["d"] = _prepend_q(df[1])
    return df_out

def _prepend_q(series: pd.Series) -> pd.Series:
    return series.apply(lambda s: None if s is None else f"q{s}")

if __name__ == "__main__":
    print(split_on_q(get_input()))

输出量:

a   b     c     d
0  a   1   198   q24
1  a   2   128    q6
2  a   6  1456  None
3  b   7    67   q22
4  b   1    56  None
5  c   3   451    q2
6  d  11     1  q789
plicqrtu

plicqrtu2#

有多种方法可以做到这一点,但一种方法是在'q'上拆分列后使用pd.concat

# temp dataframe
df2 = pd.DataFrame(df['C'].str.split('q').to_list(), columns=['C','D'])
# append to original 
df = pd.concat([df.drop(columns=['C']), df2], axis=1)
print(df)

打印:

A   B     C     D
0  a   1   198    24
1  a   2   128     6
2  a   6  1456  None
3  b   7    67    22
4  b   1    56  None
5  c   3   451     2
6  d  11     1   789
wztqucjr

wztqucjr3#

验证码

使用str.extract

df.assign(D=df['C'].str.extract(r'(q\d*)'))

产出:

A   B   C       D
0   a   1   198q24  q24
1   a   2   128q6   q6
2   a   6   1456    NaN
3   b   7   67q22   q22
4   b   1   56      NaN
5   c   3   451q2   q2
6   d   11  1q789   q789

我意识到我忽略了改变C列的必要性。来自@user19077881的建议。然后使用以下代码

df[['C', 'D']] = df['C'].str.extract(r'(\d+)(q\d+)*')

产出:

A   B   C       D
0   a   1   198     q24
1   a   2   128     q6
2   a   6   1456    NaN
3   b   7   67      q22
4   b   1   56      NaN
5   c   3   451     q2
6   d   11  1       q789

如果你不想替换原始df,使用下面代码:

df[['A', 'B']].join(df['C'].str.extract(r'(?P<C>\d+)(?P<D>q\d+)*'))

示例代码

import pandas as pd
data1 = {'A': ['a', 'a', 'a', 'b', 'b', 'c', 'd'], 
         'B': [1, 2, 6, 7, 1, 3, 11], 
         'C': ['198q24', '128q6', '1456', '67q22', '56', '451q2', '1q789']}
df = pd.DataFrame(data1)

相关问题