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

rvpgvaaj  于 2022-12-28  发布在  其他
关注(0)|答案(6)|浏览(263)

我有一个数据框,其中有一列列表,可以使用以下命令创建:

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'})

Dataframe 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

我已经尝试了各种方法,包括从How do I convert a list in a Pandas DF 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, ', ,,  , '...
jm81lzqq

jm81lzqq1#

列表理解

如果性能很重要,我强烈推荐此解决方案和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

带有DataFrame.aggpd.DataFrame构造函数

非循环/非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
pbpqsu0x

pbpqsu0x2#

一种方法是使用列表解析、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
dojqjjoe

dojqjjoe3#

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

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

egdjgwm84#

前面的解释很好很直接,但是如果你想把多个列转换成字符串分隔格式,你可以在dataframe中应用下面的函数,如果任何一列是列表,那么它将转换成字符串格式。

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])
7eumitmz

7eumitmz5#

由于我们返回的序列长度与输入的序列长度相同,并且只使用一个序列作为输入,所以我立刻想到了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()性能更好,但我不确定列表理解的比较。

qnakjoqk

qnakjoqk6#

管道:

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'

相关问题