【问题标题】:Pandas Series of lists to one seriesPandas 系列列表到一个系列
【发布时间】:2015-09-02 07:12:13
【问题描述】:

我有一个 Pandas 系列的字符串列表:

0                           [slim, waist, man]
1                                [slim, waistline]
2                                     [santa]

如您所见,列表因长度而异。我想要一种有效的方法将其折叠成一个系列

0 slim
1 waist
2 man
3 slim
4 waistline
5 santa

我知道我可以使用

series_name.split(' ')

但我很难将这些字符串重新放入一个列表中。

谢谢!

【问题讨论】:

标签: python string list pandas series


【解决方案1】:

如果您的pandas 版本太旧而无法使用series_name.explode(),这也应该可以:

from itertools import chain

pd.Series(
    chain.from_iterable(
        value
        for i, value
        in series_name.iteritems()
    )
)

【讨论】:

    【解决方案2】:

    在pandas 版本0.25.0 中出现了seriesdataframes 的新方法'explode'。旧版本没有这种方法。

    它有助于构建您需要的结果。

    例如你有这样的系列:

    import pandas as pd
    
    s = pd.Series([
        ['slim', 'waist', 'man'],
        ['slim', 'waistline'],
        ['santa']])
    

    然后就可以使用了

    s.explode()
    

    要得到这样的结果:

    0         slim
    0        waist
    0          man
    1         slim
    1    waistline
    2        santa
    

    如果是数据框:

    df = pd.DataFrame({
      's': pd.Series([
        ['slim', 'waist', 'man'],
        ['slim', 'waistline'],
        ['santa']
       ]),
       'a': 1
    })
    

    你会有这样的DataFrame:

                        s  a
    0  [slim, waist, man]  1
    1   [slim, waistline]  1
    2             [santa]  1
    

    s 列上应用爆炸:

    df.explode('s')
    

    会给你这样的结果:

               s  a
    0       slim  1
    0      waist  1
    0        man  1
    1       slim  1
    1  waistline  1
    2      santa  1
    

    如果您的系列包含空列表

    import pandas as pd
    
    s = pd.Series([
        ['slim', 'waist', 'man'],
        ['slim', 'waistline'],
        ['santa'],
        []
    ])
    

    然后运行 ​​explode 将为空列表引入 NaN 值,如下所示:

    0         slim
    0        waist
    0          man
    1         slim
    1    waistline
    2        santa
    3          NaN
    

    如果不想这样,可以dropna方法调用:

    s.explode().dropna()
    

    要得到这个结果:

    0         slim
    0        waist
    0          man
    1         slim
    1    waistline
    2        santa
    

    Dataframes 也有dropna 方法:

    df = pd.DataFrame({
      's': pd.Series([
        ['slim', 'waist', 'man'],
        ['slim', 'waistline'],
        ['santa'],
        []
       ]),
       'a': 1
    })
    

    在没有 dropna 的情况下运行 explode

    df.explode('s')
    

    将导致:

               s  a
    0       slim  1
    0      waist  1
    0        man  1
    1       slim  1
    1  waistline  1
    2      santa  1
    3        NaN  1
    

    使用dropna:

    df.explode('s').dropna(subset=['s'])
    

    结果:

               s  a
    0       slim  1
    0      waist  1
    0        man  1
    1       slim  1
    1  waistline  1
    2      santa  1
    

    【讨论】:

      【解决方案3】:

      你也可以试试:

      combined = []
      for i in s.index:
          combined = combined + s.iloc[i]
      
      print(combined)
      
      s = pd.Series(combined)
      print(s)
      

      输出:

      ['slim', 'waist', 'man', 'slim', 'waistline', 'santa']
      
      0         slim
      1        waist
      2          man
      3         slim
      4    waistline
      5        santa
      
      dtype: object
      

      【讨论】:

        【解决方案4】:

        可以使用此函数进行展平和取消展平

        def flatten(df, col):
            col_flat = pd.DataFrame([[i, x] for i, y in df[col].apply(list).iteritems() for x in y], columns=['I', col])
            col_flat = col_flat.set_index('I')
            df = df.drop(col, 1)
            df = df.merge(col_flat, left_index=True, right_index=True)
        
            return df
        

        去扁平化:

        def unflatten(flat_df, col):
            flat_df.groupby(level=0).agg({**{c:'first' for c in flat_df.columns}, col: list})
        

        展开后,除了列顺序,我们得到相同的数据框:

        (df.sort_index(axis=1) == unflatten(flatten(df)).sort_index(axis=1)).all().all()
        >> True
        

        【讨论】:

          【解决方案5】:
          series_name.sum()
          

          完全满足您的需求。请确保它是一系列列表,否则您的值将被连接(如果是字符串)或添加(如果是 int)

          【讨论】:

            【解决方案6】:

            这是一个只使用 pandas 函数的简单方法:

            import pandas as pd
            
            s = pd.Series([
                ['slim', 'waist', 'man'],
                ['slim', 'waistline'],
                ['santa']])
            

            然后

            s.apply(pd.Series).stack().reset_index(drop=True)
            

            提供所需的输出。在某些情况下,您可能希望保存原始索引并添加第二级来索引嵌套元素,例如

            0  0         slim
               1        waist
               2          man
            1  0         slim
               1    waistline
            2  0        santa
            

            如果这是您想要的,只需从链中省略 .reset_index(drop=True)

            【讨论】:

            • 请记住,s.apply(pd.Series) 正在创建一个 DataFrame,其宽度是原始系列中最长的列表。因此,如果您有一个包含 10 个列表的系列,其中一个是 500 个条目,它将生成一个包含 10 行、500 列以及可能有很多 NA 的 DataFrame!
            • 另外请记住,如果输入为空,apply 将返回一个系列,并且系列对象没有堆栈方法...
            • 对我来说太慢了。
            【解决方案7】:

            您可以尝试使用 itertools.chain 来简单地展平列表:

            In [70]: from itertools import chain
            In [71]: import pandas as pnd
            In [72]: s = pnd.Series([['slim', 'waist', 'man'], ['slim', 'waistline'], ['santa']])
            In [73]: s
            Out[73]: 
            0    [slim, waist, man]
            1     [slim, waistline]
            2               [santa]
            dtype: object
            In [74]: new_s = pnd.Series(list(chain(*s.values)))
            In [75]: new_s
            Out[75]: 
            0         slim
            1        waist
            2          man
            3         slim
            4    waistline
            5        santa
            dtype: object
            

            【讨论】:

              【解决方案8】:

              您基本上只是想在此处展平嵌套列表。

              您应该能够迭代该系列的元素:

              slist =[]
              for x in series:
                  slist.extend(x)
              

              或者更流畅(但更难理解)的列表理解:

              slist = [st for row in s for st in row]
              

              【讨论】:

                【解决方案9】:

                您可以使用如下的列表连接运算符 -

                lst1 = ['hello','world']
                lst2 = ['bye','world']
                newlst = lst1 + lst2
                print(newlst)
                >> ['hello','world','bye','world']
                

                或者你可以使用list.extend()函数如下-

                lst1 = ['hello','world']
                lst2 = ['bye','world']
                lst1.extend(lst2)
                print(lst1)
                >> ['hello', 'world', 'bye', 'world']
                

                使用extend 函数的好处是它可以处理多种类型,而concatenation 运算符仅在LHS 和RHS 都是列表时才有效。

                extend函数的其他例子-

                lst1.extend(('Bye','Bye'))
                >> ['hello', 'world', 'Bye', 'Bye']
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2015-11-26
                  • 2019-11-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-12-06
                  • 2022-01-26
                  相关资源
                  最近更新 更多