我有一个数据帧有一个(字符串)列,我想把它分成两个(字符串)列,其中一个列标题为“fips”和另一个“行”

我的数据框架df看起来是这样的:

          row
0    00000 UNITED STATES
1    01000 ALABAMA
2    01001 Autauga County, AL
3    01003 Baldwin County, AL
4    01005 Barbour County, AL

我不知道如何使用df.row。Str[:]来实现拆分行单元格的目标。我可以使用df['fips'] = hello添加一个新列,并用hello填充它。什么好主意吗?

         fips       row
0    00000 UNITED STATES
1    01000 ALABAMA 
2    01001 Autauga County, AL
3    01003 Baldwin County, AL
4    01005 Barbour County, AL

当前回答

你可以使用正则表达式模式将不同的部分非常整齐地提取出来:

In [11]: df.row.str.extract('(?P<fips>\d{5})((?P<state>[A-Z ]*$)|(?P<county>.*?), (?P<state_code>[A-Z]{2}$))')
Out[11]: 
    fips                    1           state           county state_code
0  00000        UNITED STATES   UNITED STATES              NaN        NaN
1  01000              ALABAMA         ALABAMA              NaN        NaN
2  01001   Autauga County, AL             NaN   Autauga County         AL
3  01003   Baldwin County, AL             NaN   Baldwin County         AL
4  01005   Barbour County, AL             NaN   Barbour County         AL

[5 rows x 5 columns]

要解释有点长的正则表达式:

(?P<fips>\d{5})

匹配五个数字(\d),并将其命名为“fips”。

下一部分:

((?P<state>[A-Z ]*$)|(?P<county>.*?), (?P<state_code>[A-Z]{2}$))

(|)做以下两件事之一:

(?P<state>[A-Z ]*$)

匹配任何大写字母或空格([A-Z])的数字(*),并将此“状态”命名在字符串($)结束之前,

or

(?P<county>.*?), (?P<state_code>[A-Z]{2}$))

匹配任何其他(.*) 一个逗号和一个空格 匹配字符串($)结尾前的两位数字state_code。

在这个例子中: 请注意,前两行命中了“州”(将NaN留在县和state_code列中),而最后三行命中了县和state_code(将NaN留在州列中)。

其他回答

也许有更好的方法,但这是一种方法:

                            row
    0       00000 UNITED STATES
    1             01000 ALABAMA
    2  01001 Autauga County, AL
    3  01003 Baldwin County, AL
    4  01005 Barbour County, AL
df = pd.DataFrame(df.row.str.split(' ',1).tolist(),
                                 columns = ['fips','row'])
   fips                 row
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL

没想到我还没见过这个。如果你只需要两段,我强烈推荐…

Series.str.partition

分区在分隔符上执行一次分割,通常性能相当好。

df['row'].str.partition(' ')[[0, 2]]

       0                   2
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL

如果需要重命名行,

df['row'].str.partition(' ')[[0, 2]].rename({0: 'fips', 2: 'row'}, axis=1)

    fips                 row
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL

如果你需要把它连接回原来的,使用join或concat:

df.join(df['row'].str.partition(' ')[[0, 2]])

pd.concat([df, df['row'].str.partition(' ')[[0, 2]]], axis=1)

                        row      0                   2
0       00000 UNITED STATES  00000       UNITED STATES
1             01000 ALABAMA  01000             ALABAMA
2  01001 Autauga County, AL  01001  Autauga County, AL
3  01003 Baldwin County, AL  01003  Baldwin County, AL
4  01005 Barbour County, AL  01005  Barbour County, AL

你可以使用正则表达式模式将不同的部分非常整齐地提取出来:

In [11]: df.row.str.extract('(?P<fips>\d{5})((?P<state>[A-Z ]*$)|(?P<county>.*?), (?P<state_code>[A-Z]{2}$))')
Out[11]: 
    fips                    1           state           county state_code
0  00000        UNITED STATES   UNITED STATES              NaN        NaN
1  01000              ALABAMA         ALABAMA              NaN        NaN
2  01001   Autauga County, AL             NaN   Autauga County         AL
3  01003   Baldwin County, AL             NaN   Baldwin County         AL
4  01005   Barbour County, AL             NaN   Barbour County         AL

[5 rows x 5 columns]

要解释有点长的正则表达式:

(?P<fips>\d{5})

匹配五个数字(\d),并将其命名为“fips”。

下一部分:

((?P<state>[A-Z ]*$)|(?P<county>.*?), (?P<state_code>[A-Z]{2}$))

(|)做以下两件事之一:

(?P<state>[A-Z ]*$)

匹配任何大写字母或空格([A-Z])的数字(*),并将此“状态”命名在字符串($)结束之前,

or

(?P<county>.*?), (?P<state_code>[A-Z]{2}$))

匹配任何其他(.*) 一个逗号和一个空格 匹配字符串($)结尾前的两位数字state_code。

在这个例子中: 请注意,前两行命中了“州”(将NaN留在县和state_code列中),而最后三行命中了县和state_code(将NaN留在州列中)。

我更喜欢导出相应的pandas系列(即我需要的列),使用apply函数将列内容拆分为多个系列,然后将生成的列连接到现有的DataFrame。当然,源列应该被删除。

如。

 col1 = df["<col_name>"].apply(<function>)
 col2 = ...
 df = df.join(col1.to_frame(name="<name1>"))
 df = df.join(col2.toframe(name="<name2>"))
 df = df.drop(["<col_name>"], axis=1)

分割两个单词的字符串函数应该是这样的:

lambda x: x.split(" ")[0] # for the first element
lambda x: x.split(" ")[-1] # for the last element
df[['fips', 'row']] = df['row'].str.split(' ', n=1, expand=True)