【问题标题】:How to create strings from dataframe columns elements in Python?如何从 Python 中的数据框列元素创建字符串?
【发布时间】:2018-04-14 03:59:44
【问题描述】:

给定一个数据框df,(现实生活是+1000行df)。 ColB 的元素是列表的列表。

  ColA    ColB
0  'A'    [['a','b','c'],['d','e','f']]
1  'B'    [['f','g','h'],['i','j','k']]
2  'A'    [['l','m','n'],['o','p','q']]

如何使用不同列中的元素有效地创建ColC,它是一个字符串,如下所示:

      ColC
'A>+a b:c,+d e:f'
'B>+f g:h,+i j:k'
'A>+l m:n,+o p:q'

我尝试使用df.apply 沿着这些思路,inspired by this

df['ColC'] = df.apply(lambda x:'%s>' % (x['ColA']),axis=1)

这适用于字符串的前 2 个元素。其他人很难相处。

【问题讨论】:

    标签: python string pandas dataframe


    【解决方案1】:

    这样的?

    df['ColC']  = df.ColA + '>+' + df.ColB.str[0].str[0] + \
                  ' ' + df.ColB.str[0].str[1] + ':' + \
                  df.ColB.str[0].str[2] + ',+' + \
                  df.ColB.str[1].str[0] + ' ' + \
                  df.ColB.str[1].str[1] + ':' + \
                  df.ColB.str[1].str[2]
    

    输出:

      ColA                    ColB             ColC
    0    A  [[a, b, c], [d, e, f]]  A>+a b:c,+d e:f
    1    B  [[f, g, h], [i, j, k]]  B>+f g:h,+i j:k
    2    A  [[l, m, n], [o, p, q]]  A>+l m:n,+o p:q
    

    时间

    df = pd.concat([df]*333)

    温氏法

    %%timeit df[['t1','t2']]=df['ColB'].apply(pd.Series).applymap(lambda x : ('{} {}:{}'.format(x[0],x[1],x[2]))) df.ColA+'>+'+df.t1+',+'+df.t2

    1 次循环,3 次取胜:每个循环 363 毫秒

    miradulo 方法

    %%timeit df.apply(lambda r:'{}>+{} {}:{},+{} {}:{}'.format(*flatten(r)),axis=1)

    10 次循环,3 次中的最佳:每个循环 74.9 毫秒

    斯科特波士顿法

    %%timeit df.ColA + '>+' + df.ColB.str[0].str[0] + \ ' ' + df.ColB.str[0].str[1] + ':' + \ df.ColB.str[0].str[2] + ',+' + \ df.ColB.str[1].str[0] + ' ' + \ df.ColB.str[1].str[1] + ':' + \ df.ColB.str[1].str[2]

    100 次循环,最好的 3 次:每个循环 12.4 毫秒

    【讨论】:

    • @Wen LOL... 今晚过后。今天必须支持太空人!
    • @miradulo 哦...我将原始数据的大小乘以 333 以模拟 1000 行。
    • @ScottBoston 啊,很公平 - 我猜一旦行变得足够大,粗暴的字符串表示方法就会主导性能,+1
    • @ScottBoston 是的,但据我所知,这是概括的唯一方法......叹息。
    【解决方案2】:

    如果我们使用flatten函数如下

    def flatten(l):
        for el in l:
            if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
                yield from flatten(el)
            else:
                yield el
    

    正如在this answer 中看到的那样,我们可以轻松地apply 使用扁平元素格式化字符串。

    >>> df.apply(lambda r:'{}>+{} {}:{},+{} {}:{}'.format(*flatten(r.values)), axis=1)
    0    A>+a b:c,+d e:f
    1    B>+f g:h,+i j:k
    2    A>+l m:n,+o p:q
    dtype: object
    

    这有望很好地概括。

    >>> row_formatter = lambda r: '{}>+{} {}:{},+{} {}:{}'.format(*flatten(r.values))
    >>> df.apply(row_formatter, 1)
    0    A>+a b:c,+d e:f
    1    B>+f g:h,+i j:k
    2    A>+l m:n,+o p:q
    dtype: object
    

    【讨论】:

      【解决方案3】:

      另一个答案:

      df['ColC'] = df.apply(lambda x: '%s>+%s %s:%s,+%s%s:%s'% tuple([x['ColA']]+x['ColB'][0]+x['ColB'][1]),axis=1)
      

      【讨论】:

        【解决方案4】:

        这是我的 2 美分,也使用 apply

        定义一个可应用于数据框并使用字符串格式解析列的函数

        def get_string(x):
            col_a = x.ColA
            col_b = (ch for ch in x.ColB if ch.isalnum())
            string = '{0}>+{1} {2}:{3},+{4} {5}:{6}'.format(col_a.strip("\'"), *col_b)
            return(string)
        
        df['ColC'] = df.apply(get_string, axis=1)
        df.ColC
        
        0    A>+a b:c,+d e:f
        1    B>+f g:h,+i j:k
        2    A>+l m:n,+o p:q
        

        我喜欢这个,因为它很容易修改格式,虽然以这种方式使用 apply 可能会很慢

        【讨论】:

          【解决方案5】:

          你是对的使用apply

          df[['t1','t2']]=df['colB'].apply(pd.Series).applymap(lambda x : ('{} {}:{}'.format(x[0],x[1],x[2])))
          df.colA+'>+'+df.t1+',+'+df.t2
          Out[648]: 
          0    A>+a b:c,+d e:f
          1    B>+f g:h,+i j:k
          2    C>+l m:n,+o p:q
          

          【讨论】:

          • @hernanavella 我创建了两个新列来恢复临时值:-),然后我们可以使用简单的添加来创建你想要的字符串
          猜你喜欢
          • 2021-08-18
          • 1970-01-01
          • 1970-01-01
          • 2014-02-10
          • 2018-05-27
          • 2016-10-14
          • 2019-02-12
          • 1970-01-01
          • 2020-01-14
          相关资源
          最近更新 更多