解决办法
# df.loc[my_index]会筛选所有索引=my_index的行
my_df = pd.DataFrame(
data=[1,2,3],
index=['a']*2 + ['A'],
columns=['b']
)
# 解决办法:不要循环index然后loc,而是循环range(shape[0])然后iloc,
# 加入字典,字典对应键名则为index[i]
# 结果,同名index最后一行的定位结果会覆盖前面的键值
my_dict = {}
for i in range(my_df.shape[0]):
my_dict[my_df.index[i]] = my_df.iloc[i, 0]
my_dict
应用
'''读取配置表'''
# 解除后台占用
os.system("taskkill /f /im excel.exe")
# 地址_配置表
str_addr_configuration = "配置表.xlsx"
# 字典_配置表
dict_configuration = {}
for i in pd.ExcelFile(str_addr_configuration).sheet_names:
df_configuration_i = pd.read_excel(str_addr_configuration, sheet_name=i, index_col='name').astype(str)
for j in range(df_configuration_i.shape[0]):
str_index = df_configuration_i.index[j]
dict_configuration[str_index] = df_configuration_i.iloc[j, 0]
总结:
# 与cyclone读取配置表的区别在于
# cyclone是
# 遍历工作簿的每一个sheet:
# 读取范围数据(不区分首行为列名) # 所以首行name,value在并且是第一个被赋值在字典中
# 遍历范围数据:
# 字典键名=该行第一列的值
# 字典键值=该行第二列的值
# python是
# 遍历工作簿的每一个sheet:
# 读取表格(首行为列名,首列设为行标签,第二列转为首列)
# 遍历表格的行位置:
# 字典[行标签]=表格.iloc[行位置, 第一列] # 这样可以有效针对每一行进行覆盖
# 或者遍历表格的行标签:
# 字典[行标签]=表格.loc[行标签, 第一列] # 这样当同一sheet内,行标签重名时,结果就会存在一个键名对应一个Series键值
'''
这是由于,一个行标签可能重名(对应多个行),loc筛选出来的是Series
遍历表格的行标签,在遍历到重复行标签行时,只是不断重复同一个行标签的操作
字典对应键值(该行标签)不断覆盖的也只是同一个筛选结果(一个Series键值)
'''
问题背景:
读取表格(将首列设为索引, 第二列即为第一列)
将zip(索引和对应第一列的值)添加到字典
会和预想的不一样
预想中索引相同的值将会在字典的同键名中覆盖
实际却是这个样子:
# df.loc[my_index]会筛选所有索引=my_index的行
my_df = pd.DataFrame(
data=[1,2,3],
index=['a']*3,
columns=['b']
)
my_df.loc['a']
my_dict = {}
for i in my_df.index:
my_dict[i] = my_df.loc[i, 'b']
my_dict
解答:
# 原因是,df.loc[my_index]筛选结果是Series或DataFrame,所以,
# 虽然for i in df.index 遍历了index,
# 但是对于loc来说,你只是遍历了有多少个不同的index,对于相同的index,输出的是同一个值(loc筛选结果)
# 同样,对于dict,键名不断覆盖,所赋的值仍然是同一个值(loc筛选结果)