我有一个小数据帧。下面给出一个例子。
+-------+---------+---------+------+----------+
| 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
的余数,并从值400
中取700
。< / p>
为了弥补赤字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 |
+------+---------+---------+------+----------+
surplus
和deficit
列中的值可能不同。
我无法为此任务找到算法。我会很感激任何想法。
答案 0 :(得分:2)
我害怕我不认识大熊猫所以我不能详细说明答案,但这是一个普遍的算法,我觉得它会很好。你可以将它与pandas API相匹配。
对于“已来”栏目:
max(cumsum(deficit), sum(surplus))
对于“来了”栏目(如果sum(surplus) >= sum(deficit)
):
对于“消失”专栏:只做与上面完全相同的事情,扭转“赤字”和“盈余”。
编辑:在你的例子中,过去的列是棘手的,因为在那种情况下,总和(不足)&lt;总和(盈余)。以上是关于盈余的上述程序。
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()
是计算该列所需的关键方法;见this question
编辑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)
实际上等于前一行的cumsum(不足),如果这是第一行,则为0。)答案 1 :(得分:0)
问题“如何根据pandas中的条件将列值分配给其他列?”也许函数 np.where 就是你要找的东西:
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"] )