<h2>编辑</h2>
<p><strong>(我不喜欢上一个答案,它太混乱了,所以我重新排序,并进行了更系统的测试)。</strong></p>
<h2>长话短说:</h2>
<p>对于速度,只需使用:</p>
<pre><code>def str_to_list(s):
return s[1:-1].replace('\'', '').split(', ')
df['product_name'].apply(str_to_list).to_list()
</code></pre>
<hr/>
<h2>长话短说:</h2>
<p>我们来分析一下你的代码:</p>
<pre class="lang-py prettyprint-override"><code>order_ls = raw_df['product_name'].tolist()
cln_order_ls = list()
for i in order_ls:
i = i.replace('[', '')
i = i.replace(']', '')
i = i.replace('\'', '')
cln_order_ls.append(i)
new_cln_order_ls = list()
for i in cln_order_ls:
new_cln_order_ls.append(i.split(', '))
</code></pre>
<p>您真正想做的是拥有一个函数,比如<code>str_to_list()</code>,它将您的输入<code>str</code>转换为<code>list</code>。你知道吗</p>
<p>出于某些原因,您可以分多个步骤来完成,但这确实不是必需的。到目前为止,您所拥有的可以重写为:</p>
<pre><code>def str_to_list_OP(s):
return s.replace('[', '').replace(']', '').replace('\'', '').split(', ')
</code></pre>
<p>如果可以假定<code>[</code>和<code>]</code>始终是字符串的第一个和最后一个字符,则可以将其简化为:</p>
<pre><code>def str_to_list(s):
return s[1:-1].replace('\'', '').split(', ')
</code></pre>
<p>也应该更快。你知道吗</p>
<p>其他方法将使用正则表达式,例如:</p>
<pre><code>def str_to_list_regex(s):
regex = re.compile(r'[\[\]\']')
return re.sub(regex, '', s).split(', ')
</code></pre>
<p>注意到目前为止所有的方法都使用<code>split()</code>。这是一个相当快的实现,接近C速度,几乎没有任何Python构造能打败它。你知道吗</p>
<p>所有这些方法都非常不安全,因为它们没有正确考虑转义,例如,对于以下有效的Python代码,上述所有方法都将失败:</p>
<pre><code>['ciao', "pippo", 'foo, bar']
</code></pre>
<p>在这种情况下,更可靠的替代方案是:</p>
<ol>
<li><code>ast.literal_eval</code>它适用于任何有效的Python代码</li>
<li><code>json.loads</code>这实际上需要有效的JSON字符串,因此它实际上不是一个选项。你知道吗</li>
</ol>
<p>这些解决方案的速度比较如下:</p>
<p><a href="https://i.stack.imgur.com/UPPq0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UPPq0.png" alt="benchmark1"/></a></p>
<p>正如你所见,安全是以速度为代价的。你知道吗</p>
<p>(这些图是使用<a href="https://github.com/norok2/BenchmarkTemplateIPY/blob/master/BenchmarkingTemplate.ipynb" rel="nofollow noreferrer">these scripts</a>生成的</p>
<pre class="lang-py prettyprint-override"><code>def gen_input(n):
return str([str(x) for x in range(n)])
def equal_output(a, b):
return a == b
input_sizes = (5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000)
funcs = str_to_list_OP, str_to_list, str_to_list_regex, ast.literal_eval
runtimes, input_sizes, labels, results = benchmark(
funcs, gen_input=gen_input, equal_output=equal_output,
input_sizes=input_sizes)
</code></pre>
<hr/>
<p>现在让我们集中精力讨论循环。您所做的是显式循环,我们知道Python在这方面的速度通常不是很快。
但是,理解中的循环可以更快,因为它可以生成更优化的代码。
另一种方法是使用Pandas原语的向量化表达式,可以使用<code>apply()</code>或<code>.str.</code>链。你知道吗</p>
<p>获得以下计时,表明对于较小的输入,理解最快,尽管矢量化的解决方案(使用<code>apply</code>)赶上并最终超过理解:</p>
<p><a href="https://i.stack.imgur.com/C4hsS.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/C4hsS.png" alt="benchmark2"/></a></p>
<p>使用了以下测试功能:</p>
<pre class="lang-py prettyprint-override"><code>import pandas as pd
def str_to_list(s):
return s[1:-1].replace('\'', '').split(', ')
def func_OP(df):
order_ls = df['product_name'].tolist()
cln_order_ls = list()
for i in order_ls:
i = i.replace('[', '')
i = i.replace(']', '')
i = i.replace('\'', '')
cln_order_ls.append(i)
new_cln_order_ls = list()
for i in cln_order_ls:
new_cln_order_ls.append(i.split(', '))
return new_cln_order_ls
def func_QuangHoang(df):
return df['product_name'].str[1:-1].str.replace('\'','').str.split(', ').to_list()
def func_apply_df(df):
return df['product_name'].apply(str_to_list).to_list()
def func_compr(df):
return [str_to_list(s) for s in df['product_name']]
</code></pre>
<p>具有以下测试代码:</p>
<pre class="lang-py prettyprint-override"><code>def gen_input(n):
return pd.DataFrame(
columns=('order_id', 'product_name'),
data=[[i, "['ciao', 'pippo', 'foo', 'bar', 'baz']"] for i in range(n)])
def equal_output(a, b):
return a == b
input_sizes = (5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000)
funcs = func_OP, func_QuangHoang, func_apply_df, func_compr
runtimes, input_sizes, labels, results = benchmark(
funcs, gen_input=gen_input, equal_output=equal_output,
input_sizes=input_sizes)
</code></pre>
<p>再次使用与之前相同的<a href="https://github.com/norok2/BenchmarkTemplateIPY/blob/master/BenchmarkingTemplate.ipynb" rel="nofollow noreferrer">base scripts</a>。你知道吗</p>