【问题标题】:Filling Pandas columns with lists of unequal lengths用长度不等的列表填充 Pandas 列
【发布时间】:2018-08-14 21:16:52
【问题描述】:

我在用不等长度列表中的值填充 Pandas 数据帧时遇到问题。

nx_lists_into_df 是一个 numpy 数组列表。

我收到以下错误:

ValueError:值的长度与索引的长度不匹配

代码如下:

# Column headers
df_cols = ["f1","f2"]

# Create one dataframe fror each sheet
df1 = pd.DataFrame(columns=df_cols)
df2 = pd.DataFrame(columns=df_cols)

# Create list of dataframes to iterate through
df_list = [df1, df2]

# Lists to be put into the dataframes   
nx_lists_into_df = [[array([0, 1, 3, 4, 7]),
                     array([2, 5, 6, 8])],
                    [array([0, 1, 2, 6, 7]),
                     array([3, 4, 5, 8])]]

# Loop through each sheet (i.e. each round of k folds)
for df, test_index_list in zip_longest(df_list, nx_lists_into_df):
    counter = -1
    # Loop through each column in that sheet (i.e. each fold)
    for col in df_cols:
        print(col)
        counter += 1
        # Add 1 to each index value to start indexing at 1
        df[col] = test_index_list[counter] + 1

感谢您的帮助。

编辑:结果应该是这样的:-

print(df1)

   f1   f2
0   0    2
1   1    5
2   3    6
3   4    8
4   7  NaN

print(df2)

   f1   f2
0   0    3
1   1    4
2   2    5
3   6    8
4   7  NaN

【问题讨论】:

  • 最终结果应该是什么样子?

标签: python python-3.x pandas numpy


【解决方案1】:

如果我理解正确,这可以通过pd.concat 实现。

但请参阅@pir's solution 了解可扩展版本。

# Lists to be put into the dataframes   
nx_lists_into_df = [[array([0, 1, 3, 4, 7]),
                     array([2, 5, 6, 8])],
                    [array([0, 1, 2, 6, 7]),
                     array([3, 4, 5, 8])]]

df1 = pd.concat([pd.DataFrame({'A': nx_lists_into_df[0][0]}),
                 pd.DataFrame({'B': nx_lists_into_df[0][1]})],
                 axis=1)

#    A    B
# 0  0  2.0
# 1  1  5.0
# 2  3  6.0
# 3  4  8.0
# 4  7  NaN

df2 = pd.concat([pd.DataFrame({'C': nx_lists_into_df[1][0]}),
                 pd.DataFrame({'D': nx_lists_into_df[1][1]})],
                 axis=1)

#    C    D
# 0  0  3.0
# 1  1  4.0
# 2  2  5.0
# 3  6  8.0
# 4  7  NaN

【讨论】:

  • 是的!这是完全正确的。尽管我缩短了数据框和列表的数量以使其更易于理解。有没有办法迭代更多?
  • 您可以将[pd.DataFrame({'C': nx_lists_into_df[1][0]}), pd.DataFrame({'D': nx_lists_into_df[1][1]})] 转换为列表解析,但您需要注意数组列表中的列名和索引。
【解决方案2】:

我们将利用pd.Series 附加适当的索引,并允许我们使用pd.DataFrame 构造函数而不会抱怨长度不等。

df1, df2 = (
    pd.DataFrame(dict(zip(df_cols, map(pd.Series, d))))
    for d in nx_lists_into_df
)

print(df1)

   f1   f2
0   0  2.0
1   1  5.0
2   3  6.0
3   4  8.0
4   7  NaN

print(df2)

   f1   f2
0   0  3.0
1   1  4.0
2   2  5.0
3   6  8.0
4   7  NaN

设置

from numpy import array

nx_lists_into_df = [[array([0, 1, 3, 4, 7]),
                     array([2, 5, 6, 8])],
                    [array([0, 1, 2, 6, 7]),
                     array([3, 4, 5, 8])]]

# Column headers
df_cols = ["f1","f2"]

【讨论】:

    【解决方案3】:

    您可以像这样预定义 DataFrame 的大小(通过将索引范围设置为要添加的最长列的长度 [或大于最长列的任何大小]):

    df1 = pd.DataFrame(columns=df_cols, index=range(5))
    df2 = pd.DataFrame(columns=df_cols, index=range(5))
    
    print(df1)
        f1   f2
    0  NaN  NaN
    1  NaN  NaN
    2  NaN  NaN
    3  NaN  NaN
    4  NaN  NaN
    

    (df2同理)

    DataFrame 将自动填充 NaN。

    然后您使用 .loc 分别访问每个条目,如下所示:

    for x in range(len(nx_lists_into_df)):
        for col_idx, y in enumerate(nx_lists_into_df[x]):
            df_list[x].loc[range(len(y)), df_cols[col_idx]] = y
    
    
    print(df1)
      f1   f2
    0  0    2
    1  1    5
    2  3    6
    3  4    8
    4  7  NaN
    
    print(df2)
      f1   f2
    0  0    3
    1  1    4
    2  2    5
    3  6    8
    4  7  NaN
    

    第一个循环遍历数组的第一个维度(或您要创建的 DataFrame 的数量)。

    第二个循环遍历 DataFrame 的列值,其中 y 是当前列的值,df_cols[col_idx] 是相应的列(f1 或 f2)。

    由于行和列索引的大小与 y 相同,因此不会出现长度不匹配的情况。

    还可以查看enumerate(iterable, start=0) 函数来绕过那些“计数器”变量。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2022-01-16
      • 2022-11-30
      • 1970-01-01
      • 2012-10-30
      • 2022-01-20
      • 2022-08-09
      • 2022-08-21
      • 1970-01-01
      • 2018-10-22
      相关资源
      最近更新 更多