StyleFrame
StyleFrame copied to clipboard
AttributeError: 'Series' object has no attribute 'style'
While creating a minimal working example to illustrate a problem I run into this error:
Traceback (most recent call last):
File "C:\Users\buhtzch\Desktop\x.py", line 25, in <module>
sf.to_excel(file_path).save()
File "C:\Users\buhtzch\AppData\Roaming\Python\Python39\site-packages\styleframe\style_frame.py", line 503, in to_excel
data_df_style = self.data_df.at[index, column].style
File "C:\Users\buhtzch\AppData\Roaming\Python\Python39\site-packages\pandas\core\generic.py", line 5478, in __getattr__
return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'style'
And I don't understand the root of the problem. Maybe I did something wrong or this is a bug or edgy use case?
Version info
Python 3.9.10 (tags/v3.9.10:f2f3f53, Jan 17 2022, 15:14:21) [MSC v.1929 64 bit (AMD64)]
pandas 1.3.0
openpyxl 3.0.9
StyleFrame 4.1
This is the code to reproduce.
#!/usr/bin/env python3
import os
import sys
import pathlib
import pandas
import styleframe
import styleframe.utils
print(styleframe._versions_)
df = pandas.DataFrame(
data={
'idx1': list('AABB'),
'column with long caption': [1234, 345, 33123, 2],
}
)
df = df.set_index('idx1')
print(df)
file_path = pathlib.Path.cwd() / 'test.xlsx'
default_style = styleframe.Styler(font_size=14)
sf = styleframe.StyleFrame(df, styler_obj=default_style)
sf.to_excel(file_path).save()
os.system(str(file_path))
EDIT:
The exception is not raised when I out-comment the line df = df.set_index('idx1').
I realized how much Issues I opened today. My apologize. :) I am really willing to support you as much I can.
In case of that Issue the "problem" is located at this line https://github.com/DeepSpace2/StyleFrame/blob/c8a11172d84d4af6eab7c75e7563a00926267765/styleframe/style_frame.py#L503
The data frame in my example has an un-unique index. Pandas does support un-unique indexes. But your current code assumes that the index is unique.
The whole code of .to_excel() is to long (~200 lines). So I won't dive into it because I am scared to break something. But my suggestion would be to not iterate over the index but over the row by count via iloc[]. This makes you independent from the uniqueness of the index.
Beside that problem the to_excel() should be refactored. In the current state it is nearly impossible to understand that code by external contributors. I would give this a try if you aggree.
EDIT:
The files in tests directory are without any documentation. I would like to add a test case for that problem but don't know where. I would suggest to minimally add a docstring for each TestCase derived class to make it a bit clearer for new contributors.
Feel free to open as many issues as you can find :) I appreciate the willingness and any contribution is welcome.
-
I agree that this is a bug, I'll look into using
iloc. -
I agree that
to_excelcan and should be refactored. -
What kind of documentation would you expect to see for the tests? Perhaps we can discuss this in a new issue.
This exact error also occurs for me when iterating over a list of dataframes.
The code is:
with pd.ExcelWriter(f'_{file}', engine='xlsxwriter') as writer:
row = 0
for dataframe, data in zip(tables, metadata):
data.to_excel(writer, startrow = row , startcol = 0, index = False, header = False)
row = row + data.shape[0]
sf = StyleFrame(dataframe)
format1 = Styler(bg_color = '#DCE6F1')
sf.apply_style_by_indexes(indexes_to_style=sf.index, cols_to_style=[sf.columns[0], sf.columns[2], sf.columns[4]], styler_obj=format1)
sf.to_excel(writer, startrow = row , startcol = 0, index = False)
row = row + dataframe.shape[0] + spaces + 1
The subject dataframes in tables do have unique indices.
Hi. I can't test right now, but I guess this is due to the usage of 'xlsxwriter' as an engine. Try to use 'openpyxl' which is the only engine that styleframe supports.
I don't see how the iteration in itself can lead to this error.
Dear @gribna I also consider that your problem is separate from mine. I would recommend to open a new Issue with your example code. But improve your code and make it work out of the box including sample data. Your code is not clear for us. This would help us to analyze.
I use the "default engine" (openpyxl) set by StyleFrame but the problem occurs.
I got this issue too when exporting to excel ...
C:\anaconda3\envs\predict-comp-pipeline\lib\site-packages\styleframe\style_frame.py in to_excel(self, excel_writer, sheet_name, allow_protection, right_to_left, columns_to_hide, row_to_add_filters, columns_and_rows_to_freeze, best_fit, **kwargs)
493 for row_index, index in enumerate(self.data_df.index):
494 current_cell = sheet.cell(row=row_index + startrow + (2 if header else 1), column=col_index + startcol + 1)
--> 495 data_df_style = self.data_df.at[index, column].style
496 try:
497 if '=HYPERLINK' in str(current_cell.value):
~\AppData\Roaming\Python\Python38\site-packages\pandas\core\generic.py in __getattr__(self, name)
5137 if self._info_axis._can_hold_identifiers_and_holds_name(name):
5138 return self[name]
-> 5139 return object.__getattribute__(self, name)
5140
5141 def __setattr__(self, name: str, value) -> None:
AttributeError: 'Series' object has no attribute 'style'
Also seeing this, confirmed it is due to a duplicate index