如何使用相同的分隔符拆分列

时间:2019-06-07 11:50:26

标签: python pandas pyspark

我的数据框是这个,我想按冒号(:)拆分数据框

+------------------+
|Name:Roll_no:Class|
+------------------+
|      #ab:cd#:23:C|
|      #sd:ps#:34:A|
|      #ra:kh#:14:H|
|      #ku:pa#:36:S|
|      #ra:sh#:50:P|
+------------------+

我希望我的数据框像这样:

+-----+-------+-----+
| Name|Roll_no|Class|
+-----+-------+-----+
|ab:cd|     23|    C|
|sd:ps|     34|    A|
|ra:kh|     14|    H|
|ku:pa|     36|    S|
|ra:sh|     50|    P|
+-----+-------+-----+

3 个答案:

答案 0 :(得分:4)

如果需要按最后2个:拆分,请使用Series.str.rsplit,然后按拆分的列名称设置列,最后按索引删除第一个和最后一个#

col = 'Name:Roll_no:Class'
df1 = df[col].str.rsplit(':', n=2, expand=True)
df1.columns = col.split(':')
df1['Name'] = df1['Name'].str[1:-1]
#if only first and last value
#df1['Name'] = df1['Name'].str.strip('#')
print (df1)
    Name Roll_no Class
0  ab:cd      23     C
1  sd:ps      34     A
2  ra:kh      14     H
3  ku:pa      36     S
4  ra:sh      50     P

答案 1 :(得分:2)

使用read_csv() sep =':' quotechar ='#'

str = """Name:Roll_no:Class 
#ab:cd#:23:C 
#sd:ps#:34:A 
#ra:kh#:14:H 
#ku:pa#:36:S 
#ra:sh#:50:P"""

df = pd.read_csv(pd.io.common.StringIO(str), sep=':', quotechar='#')
>>> df
     Name  Roll_no Class
#0  ab:cd       23     C
#1  sd:ps       34     A
#2  ra:kh       14     H
#3  ku:pa       36     S
#4  ra:sh       50     P

答案 2 :(得分:0)

这是您可以在pyspark中执行的操作:

指定分隔符和阅读时的报价

如果您要从文件中读取数据,则可以将spark.read_csv与以下参数一起使用:

df = spark.read.csv("path/to/file", sep=":", quote="#", header=True)
df.show()
#+-----+-------+-----+
#| Name|Roll_no|Class|
#+-----+-------+-----+
#|ab:cd|     23|    C|
#|sd:ps|     34|    A|
#|ra:kh|     14|    H|
#|ku:pa|     36|    S|
#|ra:sh|     50|    P|
#+-----+-------+-----+

使用正则表达式

如果无法更改读取数据的方式,并且从问题中所示的DataFrame开始,则可以使用正则表达式获取所需的输出。

首先通过拆分":"上的现有列名称来获得新的列名称

new_columns = df.columns[0].split(":")
print(new_columns)
#['Name', 'Roll_no', 'Class']

对于Name列,您需要提取#之间的数据。对于其他两列,您需要删除#(和后面的":")之间的字符串,并使用pyspark.sql.functions.split提取组件

from pyspark.sql.functions import regexp_extract, regexp_replace, split

df.withColumn(new_columns[0], regexp_extract(df.columns[0], r"(?<=#).+(?=#)", 0))\
    .withColumn(new_columns[1], split(regexp_replace(df.columns[0], "#.+#:", ""), ":")[0])\
    .withColumn(new_columns[2], split(regexp_replace(df.columns[0], "#.+#:", ""), ":")[1])\
    .select(*new_columns)\
    .show()
#+-----+-------+-----+
#| Name|Roll_no|Class|
#+-----+-------+-----+
#|ab:cd|     23|    C|
#|sd:ps|     34|    A|
#|ra:kh|     14|    H|
#|ku:pa|     36|    S|
#|ra:sh|     50|    P|
#+-----+-------+-----+