当前位置: 首页 > 知识库问答 >
问题:

如何将一列(或一系列)可变长度列表转换成一个固定宽度的数据帧

华森
2023-03-14

我想将具有不同长度的列表的数据帧列(或系列)转换为具有固定列数的数据帧。

数据帧将具有与最长列表一样多的列,其他列表较短的值可以是 NaN 或任何内容。

当数据以字符串形式出现时,str模块允许使用str.split中的选项expand。但我还没有找到一个可变长度列表的等价物。

在我的示例中,列表中的类型是int,但其想法是能够使用任何类型。这可以防止简单地将Series转换为str并应用提到的扩展属性。

下面我显示了使用str.split功能运行带有列表的示例的代码,并在要转换的系列的最小示例之后运行。

我找到了一个使用 apply 的解决方案,如示例所示,但速度非常慢,因此没有用处。

import numpy as np
import pandas as pd

# Example with a list as a string
A = pd.DataFrame({'lists': [
                    '[]',
                    '[360,460,160]',
                    '[360,1,2,3,4,5,6]',
                    '[10,20,30]',
                    '[100,100,100,100]',
                    ],
                  'other': [1,2,3,4,5]
                 })
print(A['lists'].astype(str).str.strip('[]').str.split(',', expand=True))

# Example with actual lists
B = pd.DataFrame({'lists': [
                    [],
                    [360,460,160],
                    [360,1,2,3,4,5,6],
                    [10,20,30],
                    [100,100,100,100],
                ],
                  'other': [1,2,3,4,5]
                 })

# Create and pre-fill expected columns
max_len = max(B['lists'].str.len())
for idx in range(max_len):
    B[f'lists_{idx}'] = np.nan

# Use .apply to fill the columns
def expand_int_list(row, col, df):
    for idx, item in enumerate(row[col]):
        df.loc[row.name, f'{col}_{idx}'] = item
        
B.apply(lambda row: expand_int_list(row, 'lists', B), axis=1)
print(B)

输出:

     0     1     2     3     4     5     6
0       None  None  None  None  None  None
1  360   460   160  None  None  None  None
2  360     1     2     3     4     5     6
3   10    20    30  None  None  None  None
4  100   100   100   100  None  None  None
                     lists  other  lists_0  lists_1  lists_2  lists_3  \
0                       []      1      NaN      NaN      NaN      NaN   
1          [360, 460, 160]      2    360.0    460.0    160.0      NaN   
2  [360, 1, 2, 3, 4, 5, 6]      3    360.0      1.0      2.0      3.0   
3             [10, 20, 30]      4     10.0     20.0     30.0      NaN   
4     [100, 100, 100, 100]      5    100.0    100.0    100.0    100.0   

   lists_4  lists_5  lists_6  
0      NaN      NaN      NaN  
1      NaN      NaN      NaN  
2      4.0      5.0      6.0  
3      NaN      NaN      NaN  
4      NaN      NaN      NaN  

编辑和最终解决方案:使在其他问题中找到的方法失败的一个重要信息是,在我的数据中,有时我有而不是列表。

在这种情况下,使用< code>tolist()将再次生成一系列列表,Pandas不允许使用< code>B.loc[B[col]使这些单元格成为空列表。isna(),col] = []。

我找到的解决方案是只在非None的行中使用< code>tolist(),并使用原始索引使用< code>concat:

# Example with actual lists
B = pd.DataFrame({'lists': [
                    [],
                    [360,460,160],
                    None,
                    [10,20,30],
                    [100,100,100,100],
                ],
                  'other': [1,2,3,4,5]
                 })

col = 'lists'
# I need to keep the index for the concat afterwards.
extended = pd.DataFrame(B.loc[~B[col].isna(), col].tolist(),
                        index=B.loc[~B[col].isna()].index)
extended = extended.add_prefix(f'{col}_')
B = pd.concat([B, extended], axis=1)

print(B)

输出:

                  lists  other  lists_0  lists_1  lists_2  lists_3
0                    []      1      NaN      NaN      NaN      NaN
1       [360, 460, 160]      2    360.0    460.0    160.0      NaN
2                  None      3      NaN      NaN      NaN      NaN
3          [10, 20, 30]      4     10.0     20.0     30.0      NaN
4  [100, 100, 100, 100]      5    100.0    100.0    100.0    100.0

共有1个答案

上官高畅
2023-03-14

如果将嵌套列表转换为列表并传递到<code>数据帧</code>构造函数,则会像最长列表一样添加缺失值,然后<code>DataFrame。add_prefix并通过<code>数据帧附加到原始数据。join:

df = B.join(pd.DataFrame(B['lists'].tolist()).add_prefix('lists_'))
print (df)
                     lists  other  lists_0  lists_1  lists_2  lists_3  \
0                       []      1      NaN      NaN      NaN      NaN   
1          [360, 460, 160]      2    360.0    460.0    160.0      NaN   
2  [360, 1, 2, 3, 4, 5, 6]      3    360.0      1.0      2.0      3.0   
3             [10, 20, 30]      4     10.0     20.0     30.0      NaN   
4     [100, 100, 100, 100]      5    100.0    100.0    100.0    100.0   

   lists_4  lists_5  lists_6  
0      NaN      NaN      NaN  
1      NaN      NaN      NaN  
2      4.0      5.0      6.0  
3      NaN      NaN      NaN  
4      NaN      NaN      NaN  
 类似资料:
  • 问题内容: 我有两个div容器。 虽然其中一个需要为特定宽度,但我需要对其进行调整,以便另一个div占用其余空间。有什么办法可以做到吗? 问题答案: HTML: CSS: 您也可以使用这样做,这通常是一种更好的方法:如何将输入元素与其标签放在同一行?

  • 问题内容: 我正在尝试建立一个具有三列的flexbox布局,其中左列和右列具有固定的宽度,而中间列可以弯曲以填充可用空间。 尽管设置了列的尺寸,但它们似乎仍会随着窗口缩小而缩小。 有人知道如何做到这一点吗? 我需要做的另一件事是基于用户交互隐藏右列,在这种情况下,左列仍将保持其固定宽度,而中间列将填充其余空间。 问题答案: 除了使用(这是使用flexbox时的建议)之外,您还可以使用以下方法: =

  • 给定需要排序和分组的对象列表: 我想将列表分组为列表中的列表,按widgetCode分组,每个子列表的元素按照它们在原始列表中遇到的顺序排列。我知道可以使用收集器将它们分组到列表映射中: 我并不认为键是理所当然地排序的,所以我采取了额外的步骤,将整个内容加载到SortedMap类型中: 我知道我可以通过使用.values()从sortedWidgetMap获取集合,而且我猜它是一个有序集合,因为它

  • 如果我想创建一个特定长度的空列表,我如何创建它而不必手动键入括号。例如:如果我想有一个长度为32的列表,但我不想在第32个元素之前键入[,,,,...],我会怎么做? 非常感谢。

  • 问题内容: 我有两个div容器。 尽管一个需要为特定宽度,但我需要对其进行调整,以便另一个div占用其余空间。有什么办法可以做到吗? 问题答案: 请参阅: http : //jsfiddle.net/SpSjL/ (调整浏览器的宽度) HTML: CSS: 您也可以使用这样做,这通常是一种更好的方法:如何将输入元素与其标签放在同一行?

  • 问题内容: 假设我们有一个字母“ abcdefghiklimnop”。如何以有效的方式递归地生成排列在FIVE组中的此字母重复的排列? 我几天来一直在为此苦苦挣扎。任何反馈将有所帮助。 本质上,这与以下操作相同:生成给定字符串的所有排列 但是,我只希望整个字符串的长度为5。我还无法弄清楚这一点。 因此,对于“ abcdefghiklimnop”的所有长度为5的所有子串,请查找子串的排列。例如,如果