F-строка с модификаторами формата в выражении pandas запускает TypeError в Series .__ format__ - PullRequest
3 голосов
/ 05 февраля 2020

Когда я использую f-строку с модификаторами формата в выражении, используя pandas Series - я получаю TypeError. Однако то же строковое выражение прекрасно работает с обычными данными. Можно ли вообще сделать это в pandas?

работает с обычными данными:

episode = 42
frame = 4242
f"e{episode:03}_f{frame:06}.jpg"
> 'e042_f004242.jpg'

не работает с pandas.Series:

df['filename'] = f"e{df.episode:03}_f{df.frame:05}_i{df.item:05}.jpg"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-84-73001803277d> in <module>
----> 1 df['filename'] = f"e{df.episode:03}_f{df.frame:05}_i{df.item:05}.jpg"
TypeError: unsupported format string passed to Series.__format__

Ошибка типа показывает, когда я передаю модификаторы формата в f-строку. Любой вид, в том числе {df.area:.2f}. Однако без модификаторов формата я не получаю ошибки, но получаю что-то бесполезное, например e0 215\n1 1\n2 1\n3

У меня есть обходные пути, но я хотел бы использовать f-строки, так как они аккуратные.

pd.__version__
> '0.25.3'

df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 84604 entries, 0 to 84603
Data columns (total 5 columns):
episode     84604 non-null int32
frame       84604 non-null int64
item        84604 non-null int64
img_size    84604 non-null float64
bounds      84604 non-null object
dtypes: float64(1), int32(1), int64(2), object(1)
memory usage: 2.9+ MB

1 Ответ

2 голосов
/ 05 февраля 2020

К сожалению f-string не работает, если передать столбцы DataFrame, необходима обработка скалярами в DataFrame.apply с x['item'], поскольку item является действительной pandas функцией Series.item и x.item здесь вызывают ошибку:

df = pd.DataFrame({'episode':[42, 21], 'frame':[4242,4248], 'item':[20,563]})

df['filename']=df.apply(lambda x: f"e{x.episode:03}_f{x.frame:05}_i{x['item']:05}.jpg", axis=1)
print (df)
   episode  frame  item                filename
0       42   4242    20  e042_f04242_i00020.jpg
1       21   4248   563  e021_f04248_i00563.jpg

Или в понимании списка:

df['filename'] = [f"e{e:03}_f{f:05}_i{i:05}.jpg" 
                  for e,f,i  
                  in zip(df.episode, df.frame, df.item)]

Однако f-строки прекрасно работают с pd. Серии без модификаторов формата: df ['filename'] = f "e {df.episode} _f {df.frame} _i {df.item} .jpg" работает нормально.

Я думаю, что нет, потому что серия, поэтому вывод:

df['filename'] = f"e{df.episode}_f{df.frame}_i{df.item}.jpg"
print (df)
   episode  frame  item                                           filename
0       42   4242    20  e0    42\n1    21\nName: episode, dtype: int64...
1       21   4248   563  e0    42\n1    21\nName: episode, dtype: int64...
...