【问题标题】:How to split the column with same delimiter如何拆分具有相同分隔符的列
【发布时间】:2019-06-07 11:50:26
【问题描述】:

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

+------------------+
|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|
+-----+-------+-----+

【问题讨论】:

  • 您在read_csv期间尝试过使用sep=':'
  • 是的,它也会拆分名称
  • 你要的是 pandas 还是 pyspark?

标签: python pandas pyspark


【解决方案1】:

如果需要按最后 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

【讨论】:

    【解决方案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
    

    【讨论】:

    • @CoolTriks 用于 pyspark,您可以执行类似操作:df = spark.read.csv('/file/path', quote='#', sep=':', header=True)。或者对于现有字段,使用两个functions.split()(首先按'#',然后按':')来检索所需的字段。
    【解决方案3】:

    这就是你可以在 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 列,您需要提取#s 之间的数据。对于其他两列,您需要删除#s(以及以下":")之间的字符串并使用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|
    #+-----+-------+-----+
    

    【讨论】:

      猜你喜欢
      • 2012-08-10
      • 2022-01-18
      • 1970-01-01
      • 2022-11-18
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      相关资源
      最近更新 更多