【问题标题】:Selecting entries from a big pandas dataframe is slow从大熊猫数据框中选择条目很慢
【发布时间】:2018-10-18 07:50:49
【问题描述】:

我有两个 pandas 数据框:一个包含高级客户,df_premium_customer,另一个包含所有已售商品,df_sold,具有列 “customerID”(包含高级客户和其他人的 ID)、“ArticleID”、“Date”和其他几个。

这就是df_premium_customer 的样子

<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
    border: 1px solid black;
}
</style>
</head>
<body>

<h2>Bordered Table</h2>
<p>Use the CSS border property to add a border to the table.</p>

<table style="width:100%">
  <tr>
    <th>Premium_CustomerID</th>
  </tr>
  <tr>
    <td>34674324</td>
  </tr>
  <tr>
    <td>18634345</td>
  </tr>
  <tr>
    <td>99744336</td>
  </tr>
</table>

</body>
</html>

这是df_sold看起来

<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
    border: 1px solid black;
}
</style>
</head>
<body>

<h2>Bordered Table</h2>
<p>Use the CSS border property to add a border to the table.</p>

<table style="width:100%">
  <tr>
    <th>CustimerID</th>
    <th>ArticleID</th> 
    <th>Date</th>
  </tr>
  <tr>
    <td>34674324</td>
    <td>3467434</td>
    <td>20140302</td>
  </tr>
  <tr>
    <td>98674342</td>
    <td>3454234</td>
    <td>20140822</td>
  </tr>
  <tr>
    <td>74644334</td>
    <td>4444434</td>
    <td>20150321</td>
  </tr>
</table>

</body>
</html>

我需要为每个客户创建一个数据结构(我最初选择了一个 dict),以显示向每个高级客户销售的产品。

到目前为止,我使用的是以下 Python 3 代码:

sold_to_customer = {}
for customer in df_premium_customer["CustomerID"]: 
    #generate the list of indexes of this this customers appears in df_sold
    cust_index = df_sold.index[df_sold['CustomerID'] == customer].tolist()

    #add this customers as key to the dict                              
    sold_to_customer[customer] = []  

    for ind in cust_index:  
        #add the name of the things he bought,when, and for how much as values to this key     
        sold_to_customer[customer].append(list(df_sold[ind][["ArticleID","Date"]]))

这样慢!

让它运行一段时间并推断它需要 16 小时才能完成,因为我有 30 万高级客户和已售商品数据框中的数百万行条目。

【问题讨论】:

  • 你能添加一些数据样本吗?
  • @jezrael 有没有比添加屏幕截图更简单的方法(我现在可以)?我不认为 stackoverflow 允许创建表格...?
  • 最好是在文本中复制数据,最好是使用pandas example
  • 顺便说一句,可能需要merge - df_premium_customer.merge(df_sold, on="CustomerID")
  • @jezrael 直到我弄清楚熊猫示例,我快速插入了一些 HTML 表格

标签: python html pandas performance


【解决方案1】:

我相信您的问题来自熊猫。一般来说,熊猫很慢。您可能会通过使用合并或 groupby 方法获得一些加速,但我什至不确定。我相信获得加速的一种简单方法是在 numpy 中完成所有操作。 我觉得行

cust_index = df_sold.index[df_sold['CustomerID'] == customer].tolist()

您的成本很高,因为您为每位客户都这样做。

您可以做的是创建一个包含所有高级客户 ID 的字典,并查看您的所有数据。要遍历所有数据,您可以使用 for 循环,这仍然会很慢,但我相信比您使用 pandas 所做的更快。

sold_to_customer = {}
for customer in df_premium_customer["CustomerID"]: 
    #Initialize the dict
    sold_to_customer[customer] = []
data = df_sold.values
for i,j,k in data:
    sold_to_customer[i].append([j,k])

这使您只浏览一次数据,并且由于对 dict 的访问应该很快,所以您应该很高兴。 让我知道这是否加快了速度,速度是否足够或仍应优化。

【讨论】:

  • 我也检查了你的方法。你确定这是 numpy 相关的吗?因为在任何时候我实际上都不需要任何 numpy 方法。我认为这种方法还需要进一步优化。已经for item in df_sold.values: print(item[1],item[2],item[3]) 只是计算和计算而不输出任何东西..... :(
  • 我认为问题出在df_sold.values,因为df_sold 包含数百万个条目
  • 您是否尝试跟踪此版本的进度以查看需要多长时间?我很确定这比你原来的方法快,因为你曾经为每个客户检查你的整个数据集,现在它只会做一次。
  • 您可以通过在第二个for循环中导入tqdm并用tqdm(data)替换数据来跟踪进度。
  • 我担心你的方法有一个缺陷:data 中有客户不是高级客户,如上所述。所以当执行sold_to_customer[i].append([j,k])i恰好是不是premium的客户时,这个key不会出现在sold_to_customer中,所以会报错
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
相关资源
最近更新 更多