基于DataFrame索引填充空列异常:为何所有行均显示False?
问题
尝试为DataFrame(df3)添加名为Information的列,要求行索引为0时填充字符串'True',其余行填充'False',但运行后所有行(包括索引为0的行)都被填充为'False',具体代码及输出如下:
输入代码
import pandas as pd import numpy as np df1 = pd.DataFrame({'Column1': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], 'Column2': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'Column3': ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'], 'Column4': ['K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'], 'Column5': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], 'Column6': ['XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'], 'Column7': ['U', 'V', 'W', 'X', 'Y', 'Z', '', '', '', ''], 'Column8': [21, 22, 23, 24, 25, 26, pd.NA, pd.NA, pd.NA, pd.NA], 'Column9': ['XXI', 'XXII', 'XXIII', 'XXIV', 'XXV', 'XXVI', '', '', '', '']}) column_names = ['Letters', 'Numbers', 'RomanNumerals'] df3 = pd.DataFrame(columns = column_names) i=0 while i<len(df1.columns): df2 = df1.iloc[:, i:i+3] df2.columns = column_names df3 = pd.concat([df3, df2]) i+=3 df3.dropna(inplace=True) for index, row in df3.iterrows(): df3['Information'] = np.where(index == 0, True, False) display(df3)
输出结果
| Letters | Numbers | RomanNumerals | Information | |
|---|---|---|---|---|
| 0 | A | 1 | I | FALSE |
| 1 | B | 2 | II | FALSE |
| 2 | C | 3 | III | FALSE |
| 3 | D | 4 | IV | FALSE |
| 4 | E | 5 | V | FALSE |
| 5 | F | 6 | VI | FALSE |
| 6 | G | 7 | VII | FALSE |
| 7 | H | 8 | VIII | FALSE |
| 8 | I | 9 | IX | FALSE |
| 9 | J | 10 | X | FALSE |
| 0 | K | 11 | XI | FALSE |
| 1 | L | 12 | XII | FALSE |
| 2 | M | 13 | XIII | FALSE |
| 3 | N | 14 | XIV | FALSE |
| 4 | O | 15 | XV | FALSE |
| 5 | P | 16 | XVI | FALSE |
| 6 | Q | 17 | XVII | FALSE |
| 7 | R | 18 | XVIII | FALSE |
| 8 | S | 19 | XIX | FALSE |
| 9 | T | 20 | XX | FALSE |
| 0 | U | 21 | XXI | FALSE |
| 1 | V | 22 | XXII | FALSE |
| 2 | W | 23 | XXIII | FALSE |
| 3 | X | 24 | XXIV | FALSE |
| 4 | Y | 25 | XXV | FALSE |
| 5 | Z | 26 | XXVI | FALSE |
原因分析
你的循环逻辑存在根本性错误:
- 循环中执行
df3['Information'] = np.where(index == 0, True, False)时,并非给当前行赋值,而是覆盖整个Information列。 - 循环会遍历
df3的每一行,最后一次循环的index是5(最后一行的索引),此时index == 0为False,所以整个列会被最终的np.where结果覆盖,全部变成False。 - 另外,
np.where的第一个参数是单个布尔值(不是对应每行的条件数组),所以会生成一个全为相同值的数组,直接替换整列。
解决方案
方法1:向量式操作(推荐,符合Pandas最佳实践)
直接利用索引条件一次性生成整列,无需循环,效率最高:
# 生成布尔值列 df3['Information'] = df3.index == 0 # 如果需要字符串类型的'True'/'False',转换即可: df3['Information'] = (df3.index == 0).astype(str)
方法2:正确的循环赋值(不推荐,仅作演示)
如果一定要用循环,需要给当前行的指定列赋值,而非整列:
# 先默认填充所有行为'False' df3['Information'] = 'False' for index, row in df3.iterrows(): if index == 0: # 定位到当前行的Information列赋值 df3.loc[index, 'Information'] = 'True'
注意:这种行遍历循环在数据量大时效率极低,Pandas官方不推荐使用。
内容的提问来源于stack exchange,提问作者Timeless
相关产品推荐
相关产品推荐

