列表的列,将列表转换为字符串作为新列

Posted

技术标签:

【中文标题】列表的列,将列表转换为字符串作为新列【英文标题】:Column of lists, convert list to string as a new column 【发布时间】:2017-12-31 14:20:47 【问题描述】:

我有一个包含一列列表的数据框,可以通过以下方式创建:

import pandas as pd
lists=1:[[1,2,12,6,'ABC']],2:[[1000,4,'z','a']]
#create test dataframe
df=pd.DataFrame.from_dict(lists,orient='index')
df=df.rename(columns=0:'lists')

数据框df 看起来像:

                lists
1  [1, 2, 12, 6, ABC]
2     [1000, 4, z, a]

我需要创建一个名为“liststring”的新列,它获取lists 中每个列表的每个元素,并创建一个字符串,每个元素用逗号分隔。每个列表的元素可以是intfloatstring。所以结果是:

                lists    liststring
1  [1, 2, 12, 6, ABC]  1,2,12,6,ABC
2     [1000, 4, z, a]    1000,4,z,a

我尝试了各种方法,包括来自Converting a Panda DF List into a string:

df['liststring']=df.lists.apply(lambda x: ', '.join(str(x)))

但不幸的是,结果需要每个字符并用逗号分隔:

                lists                                         liststring
1  [1, 2, 12, 6, ABC]  [, 1, ,,  , 2, ,,  , 1, 2, ,,  , 6, ,,  , ', A...
2     [1000, 4, z, a]  [, 1, 0, 0, 0, ,,  , 4, ,,  , ', z, ', ,,  , '...

提前感谢您的帮助!

【问题讨论】:

这能回答你的问题吗? Converting a Panda DF List into a string 【参考方案1】:

列表理解

如果性能很重要,我强烈推荐这个解决方案和I can explain why.

df['liststring'] = [','.join(map(str, l)) for l in df['lists']]
df

                lists    liststring
0  [1, 2, 12, 6, ABC]  1,2,12,6,ABC
1     [1000, 4, z, a]    1000,4,z,a

您可以使用函数将其扩展到更复杂的用例。

def try_join(l):
    try:
        return ','.join(map(str, l))
    except TypeError:
        return np.nan

df['liststring'] = [try_join(l) for l in df['lists']]

Series.apply/Series.agg','.join

您需要先将列表项转换为字符串,这就是map 派上用场的地方。

df['liststring'] = df['lists'].apply(lambda x: ','.join(map(str, x)))

或者,

df['liststring'] = df['lists'].agg(lambda x: ','.join(map(str, x)))

df
                lists    liststring
0  [1, 2, 12, 6, ABC]  1,2,12,6,ABC
1     [1000, 4, z, a]    1000,4,z,a

pd.DataFrame 带有DataFrame.agg 的构造函数

非循环/非 lambda 解决方案。

df['liststring'] = (pd.DataFrame(df.lists.tolist())
                      .fillna('')
                      .astype(str)
                      .agg(','.join, 1)
                      .str.strip(','))

df
                lists    liststring
0  [1, 2, 12, 6, ABC]  1,2,12,6,ABC
1     [1000, 4, z, a]    1000,4,z,a

【讨论】:

压缩成df['lists'].apply(lambda x: ','.join(map(str, x)))? 此解决方案有效,并且比同样有效的@Scott Boston 略快。显然使用列表理解缓存会导致性能略有下降。谢谢。 pandas.Series.str.join 比较如何? @AMC 这是加入列表的规范解决方案,假设所有列表元素都是字符串。我没有在这里谈论它,因为它不适用于 OP 的数据。【参考方案2】:

一种方法是使用列表理解,strjoin

df['liststring'] = df.lists.apply(lambda x: ', '.join([str(i) for i in x]))

输出:

                lists        liststring
1  [1, 2, 12, 6, ABC]  1, 2, 12, 6, ABC
2     [1000, 4, z, a]     1000, 4, z, a

【讨论】:

这行得通,但比@COLDSPEED 稍微慢一些,因为列表理解缓存... 很好的解决方案,虽然赞成...【参考方案3】:

前面的解释很好,很直截了当。但是,假设您想将多列转换为字符串分隔格式。无需进入单个列,您可以将以下函数应用于数据框,如果任何列是列表,则它将转换为字符串格式。

def list2Str(lst):
    if type(lst) is list: # apply conversion to list columns
        return";".join(lst)
    else:
        return lst

df.apply(lambda x: [list2Str(i) for i in x])

当然,如果您只想应用到某些列,那么您可以选择 列的子集如下

df[['col1',...,'col2']].apply(lambda x: [list2Str(i) for i in x])

【讨论】:

【参考方案4】:

所有这些对我都不起作用(处理文本数据)对我有用的是:

    df['liststring'] = df['lists'].apply(lambda x: x[1:-1])

【讨论】:

【参考方案5】:

由于我们返回的序列长度与输入的长度相同,并且只使用一个序列作为输入,因此我们立即想到了 pd.transform。这对我有用:

df['liststring'] = (
    df['lists'] 
    .transform(
        lambda x: ",".join(map(str,x))    
    )
)

返回

                lists    liststring
1  [1, 2, 12, 6, ABC]  1,2,12,6,ABC
2     [1000, 4, z, a]    1000,4,z,a

非常感谢其他人对连接的 map() 修复。其他人也可以比我更好地引用性能优势,但我相信 transform 通常比 apply() 性能更高,但我不确定列表理解比较。

【讨论】:

【参考方案6】:

管道:

import pandas as pd
lists=1:[[1,2,12,6,'ABC']],2:[[1000,4,'z','a']]
#create test dataframe
(
    pd.DataFrame.from_dict(lists,orient='index', columns=['lists'])
    .assign(liststring=lambda x: x.lists.astype(str).str[1:-1])
)

输出:

                     lists           liststring
    1   [1, 2, 12, 6, ABC]   1, 2, 12, 6, 'ABC'
    2   [1000, 4, z, a]      1000, 4, 'z', 'a'

【讨论】:

以上是关于列表的列,将列表转换为字符串作为新列的主要内容,如果未能解决你的问题,请参考以下文章

具有表示集合列表的字符串值的列,将相关信息提取到新列

根据每个句子的第一个单词将 pandas 数据框列中的字符串列表分解为新列

将列表的每个元素中的列转换为字符串

将列中的字符串集列表转换为新列

当列表值与Pyspark数据帧中的列值的子字符串匹配时,填充新列

Pandas列表的列,通过迭代(选择)三列的每个列表元素作为新列和行来创建多列[重复]