繁体   English   中英

如何根据熊猫中的条件将列值分配到其他列

[英]How to distribute column values to another columns based on condition in pandas

我有一个小数据框。 下面给出一个例子。

+-------+---------+---------+------+----------+  
| code  | surplus | deficit | gone | has come |  
+-------+---------+---------+------+----------+
| 0100  |    1000 |       0 |      |          |
| 0103  |       0 |     100 |      |          |
| 0104  |       0 |     600 |      |          |
| 0190  |       0 |       0 |      |          |
| 0191  |       0 |     800 |      |          |
| 0192  |     500 |       0 |      |          |
| 0193  |     700 |       0 |      |          |
| 0194  |       0 |     300 |      |          |
| 0195  |       0 |       0 |      |          |
+-------+---------+---------+------+----------+

我需要从列surplus分配数据,以便覆盖列deficit的数据。 在列gone写下来,我从列多少了surplus ,并在列has come写下来,我是多么加入填补亏空。 当值减小时,我从列surplus获取数据。 并且总是从最大的赤字开始。

在我的示例中,它将如下所示:

为了弥补最大的赤字(在示例中为800 ),我取值1000一部分。

为了弥补下一个赤字(在示例中为600 ),我取值1000的余数,并从值700400

为了弥补赤字300我取值700的余数。

最后,为了弥补赤字100我加入了价值500一部分。

结果应该是下一个数据帧:

+------+---------+---------+------+----------+
| code | surplus | deficit | gone | has come |
+------+---------+---------+------+----------+
| 0100 |    1000 |       0 | 1000 |        0 |
| 0103 |       0 |     100 |    0 |      100 |
| 0104 |       0 |     600 |    0 |      600 |
| 0190 |       0 |       0 |    0 |        0 |
| 0191 |       0 |     800 |    0 |      800 |
| 0192 |     500 |       0 |  100 |        0 |
| 0193 |     700 |       0 |  700 |        0 |
| 0194 |       0 |     300 |    0 |      300 |
| 0195 |       0 |       0 |    0 |        0 |
+------+---------+---------+------+----------+

surplusdeficit列中的值可以不同。

我无法为此任务提出算法。 如有任何想法,我将不胜感激。

恐怕我不了解大熊猫,所以我无法给出答案的详细信息,但是我认为这是一个通用的算法,我认为它可以很好地工作。 您可以将它与pandas API进行匹配。

对于“已经到来”列:

  • 按不足(降序)对条目进行排序
  • 计算此排序列表中赤字条目的累积总和
  • 用sum(surplus)绑定,即创建一列max(cumsum(deficit), sum(surplus))
  • 现在,每一项与下一项的区别(我认为这是pandas.Series.diff方法?),使用0作为第“ -1”项(也许您必须添加一个虚拟行?)。 这是您的“拥有”价值

对于“ has come”列(如果sum(surplus) >= sum(deficit) ):

  • 在这种情况下,您只需为所有行设置“ has come” =“ deficit”,它将比上述计算更快
  • 但是,如果您没有明确检查这种情况,上述计算仍将有效

对于“已消失”列:只需执行与上述完全相同的操作,即可反转“赤字”和“盈余”。

编辑:在您的示例中,gone列很棘手,因为在这种情况下,sum(deficit)<sum(surplus)。 这是关于盈余的上述程序。

sum(surplus) = 2200
sum(deficit) = 1800

+------+---------+---------+-----------------+-----------------------------------+----------------+
| code | surplus | deficit | cumsum(surplus) | max(cumsum(surplus),sum(deficit)) | diff(prev row) |
+------+---------+---------+-----------------+-----------------------------------+----------------+
| NaN  |       0 |       0 |               0 |                                 0 |           NaN  |
| 0100 |    1000 |       0 |            1000 |                              1000 |           1000 |
| 0193 |     700 |       0 |            1700 |                              1700 |           700  |
| 0192 |     500 |       0 |            2200 |                              1800 |           100  |
| 0191 |       0 |     800 |            2200 |                              1800 |           0    |
| 0103 |       0 |     100 |            2200 |                              1800 |           0    |
| 0104 |       0 |     600 |            2200 |                              1800 |           0    |
| 0190 |       0 |       0 |            2200 |                              1800 |           0    |
| 0194 |       0 |     300 |            2200 |                              1800 |           0    |
| 0195 |       0 |       0 |            2200 |                              1800 |           0    |
+------+---------+---------+-----------------+-----------------------------------+----------------+

最后一列是您想要的结果。 请注意,我在开始处添加了一个虚拟行,以便可以计算成对差异。 事实证明shift()是计算该列所需的关键方法; 看到这个问题

编辑2:我认为可能值得添加替代解决方案。 有点难以理解,但是实现起来可能会更容易,因为您不需要摆弄多余的虚拟行。

  • 像以前一样:按不足(降序)对条目进行排序
  • 像以前一样:计算此排序列表中赤字条目的累积总和
  • 新增:查找第一行的索引,该行的累积总和大于盈余的总和(在熊猫中获取该总和并不容易)。 我们称其为i (如果不存在这样的行,则为i=Inf )。
  • 对于此索引之前的所有行(即df[:i] ),设置“ has come” =“ deficit”
  • 对于此索引之后的所有行(即df[i+1:] ),设置“ has come” = 0
  • 该行(即df[i]中,如果i存在),设定为“已经”到:
    • has come = sum(surplus) - (cumsum(deficit) - deficit)
    • (顺便说一句, (cumsum(deficit) - deficit)实际上等于前一行的累计(亏损);如果是第一行,则为0。)

对于问题“如何根据熊猫的状况将列值分配到其他列?” is what you are looking for: 也许功能是您要寻找的:

import numpy as np
import pandas as pd 

# df[Column title] = np.where ( condition on this line, if condition true then value to assign, else value to assign)
df["gone"] = np.where((df["surplus"] - df["deficit"]) > 0 , df["surplus"] - df["deficit"] , 0)
df["has come"] = np.where((df["surplus"] - df["deficit"]) < 0 , 0, df["deficit"] - df["surplus"] )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM