python pandas ExcelWriter 将单元格格式化为文本时出现问题
python pandas ExcelWriter issue while formatting cells as text
我需要为我的 excel sheet 列着色,该列是从 pandas 数据框写入的。
这是我将给出的示例并解释我面临的问题。
df=pd.DataFrame(columns=['A2','B18'],data=[[10,123415209123456789],[12,1223152012345678088],[10,1234152091234566666],[12,1223152012345678777]],dtype='object')
print(df)
A2 B18
0 10 123415209123456789
1 12 1223152012345678088
2 10 1234152091234566666
3 12 1223152012345678777
print(df.info)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 A2 4 non-null object
1 B18 4 non-null object
dtypes: object(2)
memory usage: 192.0+ bytes
None
我确实对颜色有一些复杂的格式要求,不仅要对齐数据,还要对齐 header。这就是我想到使用 excelwriter 而不是 pandas styler 的原因。
但是,我遇到了文本格式问题
#Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter(dataFolder + 'tmp_12_test126.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer,sheet_name='Sheet1',index=False)
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
col_format=[{},{'bg_color': 'cyan', 'num_format': '@'}]
# Start iterating through the columns and the rows to apply the format
for col in range(df.shape[1]):
for row in range(df.shape[0]):
if len(col_format[col]) > 0 :
worksheet.write(row+1,col,df.iloc[row,col],workbook.add_format(col_format[col]))
# Finally write the file
writer.save()
但是这会写入 B18 列,将其转换为科学记数法并导致丢失最后 4 位值。
任何人都可以帮助我做错什么吗?
我通读并发现 'num_format': '@' 是将单元格强制为文本格式所必需的。
但由于某种原因,它不起作用。
使用dtype=object
不会将数字转换为字符串。相反,它会尝试将每个值强制转换为最合适的 python 类型。如果你想要字符串而不是数字,你可以创建默认类型 dtype=str
(强制所有列)或使用 astype()
:
为每列选择不同的类型
import pandas as pd
df1=pd.DataFrame(columns=['A2','B18'],
data=[[10,123415209123456789],
[12,1223152012345678088],
[10,1234152091234566666],
[12,1223152012345678777]],
dtype=object)
print('df1 types:')
[print(idx,type(val[0]),type(val[1])) for idx,val in df1.iterrows()]
df2=pd.DataFrame(columns=['A2','B18'],
data=[[10,123415209123456789],
[12,1223152012345678088],
[10,1234152091234566666],
[12,1223152012345678777]],
dtype=str)
print('df2 types:')
[print(idx,type(val[0]),type(val[1])) for idx,val in df2.iterrows()]
df3=pd.DataFrame(columns=['A2','B18'],
data=[[10,123415209123456789],
[12,1223152012345678088],
[10,1234152091234566666],
[12,1223152012345678777]]).astype({'A2': int, 'B18':str})
print('df3 types:')
[print(idx,type(val[0]),type(val[1])) for idx,val in df3.iterrows()]
输出:
df1 types:
0 <class 'int'> <class 'int'>
1 <class 'int'> <class 'int'>
2 <class 'int'> <class 'int'>
3 <class 'int'> <class 'int'>
df2 types:
0 <class 'str'> <class 'str'>
1 <class 'str'> <class 'str'>
2 <class 'str'> <class 'str'>
3 <class 'str'> <class 'str'>
df3 types:
0 <class 'int'> <class 'str'>
1 <class 'int'> <class 'str'>
2 <class 'int'> <class 'str'>
3 <class 'int'> <class 'str'>
我需要为我的 excel sheet 列着色,该列是从 pandas 数据框写入的。
这是我将给出的示例并解释我面临的问题。
df=pd.DataFrame(columns=['A2','B18'],data=[[10,123415209123456789],[12,1223152012345678088],[10,1234152091234566666],[12,1223152012345678777]],dtype='object')
print(df)
A2 B18
0 10 123415209123456789
1 12 1223152012345678088
2 10 1234152091234566666
3 12 1223152012345678777
print(df.info)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 A2 4 non-null object
1 B18 4 non-null object
dtypes: object(2)
memory usage: 192.0+ bytes
None
我确实对颜色有一些复杂的格式要求,不仅要对齐数据,还要对齐 header。这就是我想到使用 excelwriter 而不是 pandas styler 的原因。
但是,我遇到了文本格式问题
#Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter(dataFolder + 'tmp_12_test126.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer,sheet_name='Sheet1',index=False)
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
col_format=[{},{'bg_color': 'cyan', 'num_format': '@'}]
# Start iterating through the columns and the rows to apply the format
for col in range(df.shape[1]):
for row in range(df.shape[0]):
if len(col_format[col]) > 0 :
worksheet.write(row+1,col,df.iloc[row,col],workbook.add_format(col_format[col]))
# Finally write the file
writer.save()
但是这会写入 B18 列,将其转换为科学记数法并导致丢失最后 4 位值。
任何人都可以帮助我做错什么吗? 我通读并发现 'num_format': '@' 是将单元格强制为文本格式所必需的。 但由于某种原因,它不起作用。
使用dtype=object
不会将数字转换为字符串。相反,它会尝试将每个值强制转换为最合适的 python 类型。如果你想要字符串而不是数字,你可以创建默认类型 dtype=str
(强制所有列)或使用 astype()
:
import pandas as pd
df1=pd.DataFrame(columns=['A2','B18'],
data=[[10,123415209123456789],
[12,1223152012345678088],
[10,1234152091234566666],
[12,1223152012345678777]],
dtype=object)
print('df1 types:')
[print(idx,type(val[0]),type(val[1])) for idx,val in df1.iterrows()]
df2=pd.DataFrame(columns=['A2','B18'],
data=[[10,123415209123456789],
[12,1223152012345678088],
[10,1234152091234566666],
[12,1223152012345678777]],
dtype=str)
print('df2 types:')
[print(idx,type(val[0]),type(val[1])) for idx,val in df2.iterrows()]
df3=pd.DataFrame(columns=['A2','B18'],
data=[[10,123415209123456789],
[12,1223152012345678088],
[10,1234152091234566666],
[12,1223152012345678777]]).astype({'A2': int, 'B18':str})
print('df3 types:')
[print(idx,type(val[0]),type(val[1])) for idx,val in df3.iterrows()]
输出:
df1 types:
0 <class 'int'> <class 'int'>
1 <class 'int'> <class 'int'>
2 <class 'int'> <class 'int'>
3 <class 'int'> <class 'int'>
df2 types:
0 <class 'str'> <class 'str'>
1 <class 'str'> <class 'str'>
2 <class 'str'> <class 'str'>
3 <class 'str'> <class 'str'>
df3 types:
0 <class 'int'> <class 'str'>
1 <class 'int'> <class 'str'>
2 <class 'int'> <class 'str'>
3 <class 'int'> <class 'str'>