使用带有列的 DataFrame 作为 str.format() 的命名参数
using a DataFrame with columns as named arguments to str.format()
我有一个像这样的 DataFrame:
import pandas as pd
df = pd.DataFrame({'author':["Melville","Hemingway","Faulkner"],
'title':["Moby Dick","The Sun Also Rises","The Sound and the Fury"],
'subject':["whaling","bullfighting","a messed-up family"]
})
我知道我可以做到:
# produces desired output
("Some guy " + df['author'] + " wrote a book called " +
df['title'] + " that uses " + df['subject'] +
" as a metaphor for the human condition.")
但是否可以使用 str.format()
将其写得更清楚,类似于:
# returns KeyError:'author'
["Some guy {author} wrote a book called {title} that uses "
"{subject} as a metaphor for the human condition.".format(x)
for x in df.itertuples(index=False)]
>>> ["Some guy {author} wrote a book called {title} that uses "
"{subject} as a metaphor for the human condition.".format(**x._asdict())
for x in df.itertuples(index=False)]
['Some guy Melville wrote a book called Moby Dick that uses whaling as a metaphor for the human condition.', 'Some guy Hemingway wrote a book called The Sun Also Rises that uses bullfighting as a metaphor for the human condition.', 'Some guy Faulkner wrote a book called The Sound and the Fury that uses a messed-up family as a metaphor for the human condition.']
请注意 _asdict()
并不是 public api 的一部分,因此依赖它可能会在以后对 pandas.[=13 的更新中中断=]
您可以这样做:
>>> ["Some guy {} wrote a book called {} that uses "
"{} as a metaphor for the human condition.".format(*x)
for x in df.values]
您也可以这样使用 DataFrame.iterrows()
:
["The book {title} by {author} uses "
"{subject} as a metaphor for the human condition.".format(**x)
for i, x in df.iterrows()]
如果你想,哪个很好:
- 使用命名参数,因此使用顺序不必与列的顺序匹配(如上)
- 不使用像
_asdict()
这样的内部函数
Timing:最快的似乎是M. Klugerford的第二个解决方案,即使我们注意到关于缓存的警告并采取最慢的运行。
# example
%%timeit
("Some guy " + df['author'] + " wrote a book called " +
df['title'] + " that uses " + df['subject'] +
" as a metaphor for the human condition.")
# 1000 loops, best of 3: 883 µs per loop
%%timeit
["Some guy {author} wrote a book called {title} that uses "
"{subject} as a metaphor for the human condition.".format(**x._asdict())
for x in df.itertuples(index=False)]
#1000 loops, best of 3: 962 µs per loop
%%timeit
["Some guy {} wrote a book called {} that uses "
"{} as a metaphor for the human condition.".format(*x)
for x in df.values]
#The slowest run took 5.90 times longer than the fastest. This could mean that an intermediate result is being cached.
#10000 loops, best of 3: 18.9 µs per loop
%%timeit
from collections import OrderedDict
["The book {title} by {author} uses "
"{subject} as a metaphor for the human condition.".format(**x)
for x in [OrderedDict(row) for i, row in df.iterrows()]]
#1000 loops, best of 3: 308 µs per loop
%%timeit
["The book {title} by {author} uses "
"{subject} as a metaphor for the human condition.".format(**x)
for i, x in df.iterrows()]
#1000 loops, best of 3: 413 µs per loop
为什么倒数第二个比最后一个快我搞不懂。
我有一个像这样的 DataFrame:
import pandas as pd
df = pd.DataFrame({'author':["Melville","Hemingway","Faulkner"],
'title':["Moby Dick","The Sun Also Rises","The Sound and the Fury"],
'subject':["whaling","bullfighting","a messed-up family"]
})
我知道我可以做到:
# produces desired output
("Some guy " + df['author'] + " wrote a book called " +
df['title'] + " that uses " + df['subject'] +
" as a metaphor for the human condition.")
但是否可以使用 str.format()
将其写得更清楚,类似于:
# returns KeyError:'author'
["Some guy {author} wrote a book called {title} that uses "
"{subject} as a metaphor for the human condition.".format(x)
for x in df.itertuples(index=False)]
>>> ["Some guy {author} wrote a book called {title} that uses "
"{subject} as a metaphor for the human condition.".format(**x._asdict())
for x in df.itertuples(index=False)]
['Some guy Melville wrote a book called Moby Dick that uses whaling as a metaphor for the human condition.', 'Some guy Hemingway wrote a book called The Sun Also Rises that uses bullfighting as a metaphor for the human condition.', 'Some guy Faulkner wrote a book called The Sound and the Fury that uses a messed-up family as a metaphor for the human condition.']
请注意 _asdict()
并不是 public api 的一部分,因此依赖它可能会在以后对 pandas.[=13 的更新中中断=]
您可以这样做:
>>> ["Some guy {} wrote a book called {} that uses "
"{} as a metaphor for the human condition.".format(*x)
for x in df.values]
您也可以这样使用 DataFrame.iterrows()
:
["The book {title} by {author} uses "
"{subject} as a metaphor for the human condition.".format(**x)
for i, x in df.iterrows()]
如果你想,哪个很好:
- 使用命名参数,因此使用顺序不必与列的顺序匹配(如上)
- 不使用像
_asdict()
这样的内部函数
Timing:最快的似乎是M. Klugerford的第二个解决方案,即使我们注意到关于缓存的警告并采取最慢的运行。
# example
%%timeit
("Some guy " + df['author'] + " wrote a book called " +
df['title'] + " that uses " + df['subject'] +
" as a metaphor for the human condition.")
# 1000 loops, best of 3: 883 µs per loop
%%timeit
["Some guy {author} wrote a book called {title} that uses "
"{subject} as a metaphor for the human condition.".format(**x._asdict())
for x in df.itertuples(index=False)]
#1000 loops, best of 3: 962 µs per loop
%%timeit
["Some guy {} wrote a book called {} that uses "
"{} as a metaphor for the human condition.".format(*x)
for x in df.values]
#The slowest run took 5.90 times longer than the fastest. This could mean that an intermediate result is being cached.
#10000 loops, best of 3: 18.9 µs per loop
%%timeit
from collections import OrderedDict
["The book {title} by {author} uses "
"{subject} as a metaphor for the human condition.".format(**x)
for x in [OrderedDict(row) for i, row in df.iterrows()]]
#1000 loops, best of 3: 308 µs per loop
%%timeit
["The book {title} by {author} uses "
"{subject} as a metaphor for the human condition.".format(**x)
for i, x in df.iterrows()]
#1000 loops, best of 3: 413 µs per loop
为什么倒数第二个比最后一个快我搞不懂。