如何在不创建新列的情况下就地更新列值?

时间:2019-01-02 09:02:09

标签: python pandas dataframe

Existing dataframe

如何使用熊猫获得所需的输出,如下所示?

Desired dataframe

A,B,C,D列为现有数量。 A1,B1,C1,D1列为短缺数量。 如何将现有数量重新分配给短缺数量的列? 现有数量应按C,B,A,D的顺序重新分配。 例如,如果A1需要10个数量,则首先应采用'C'中的值,一旦变为零,则应采用'B'列中的值。一旦A,B,C,D的所有值都变为零,则应将剩余值添加到新列“剩余”中。 请帮助解决这个问题。 谢谢。

1 个答案:

答案 0 :(得分:1)

便捷方式

我认为它将完成这项工作。您需要解决的问题是它不容易维护。如果有一天您需要一个新列,那么“ E”列的顺序是什么?

df['shortage'] = df.A1 + df.B1 + df.C1 + df.D1

df['remaining'] = df['shortage'] - df.D - df.C - df.B - df.A
df.loc[df.remaining < 0, 'remaining'] = 0

df.C = df.C - df['shortage']
df.loc[df.C < 0, 'C'] = 0

df.B = df.C + df.B - df['shortage']
df.loc[df.B < 0, 'B'] = 0

df.A = df.C + df.B + df.A - df['shortage']
df.loc[df.A < 0, 'A'] = 0

df.D = df.C + df.B + df.A + df.D - df['shortage']
df.loc[df.D < 0, 'D'] = 0

for col in ['A1', 'B1', 'C1', 'D1']:
    df.loc[df[col] != 0, col] = df.loc[df[col] != 0, 'remaining']

df = df.drop('shortage', axis=1)

动态方式

由于上述代码不是动态代码,因此我在下面提供了第二种方法,使您可以拥有新的列(例如,列“ E”) 您唯一需要维护的是订单行1

order = ['C', 'B', 'A', 'D']

# get the list of shortage_col (those which starts with 1) and non_shortage_col (the others)
shortage_col = [col for col in df.columns.tolist() if col.endswith('1')]
non_shortage_col = [col for col in df.columns.tolist() if not (col.endswith('1') | (col == 'Item'))]

# add together all columns that are in shortage_col
df['shortage'] = np.sum(df[shortage_col].values.tolist(),axis=1)

df['remaining'] = df['shortage'] - np.sum(df[non_shortage_col].values.tolist(),axis=1)
df.loc[df.remaining < 0, 'remaining'] = 0

# loop through order to get the list of all previous values for each item in order
# returns a list like that [['C'], ['C', 'B'], ['C', 'B', 'A'], ['C', 'B', 'A', 'D']]
to_add = []
for i in range(len(order)):
    list_of_previous = []
    for index, element in enumerate(order):
        if index < i + 1:
            list_of_previous.append(element)
    to_add.append(list_of_previous)

for i in range(len(order)):
    col = order[i]
    # same as : df.D = df.C + df.B + df.A + df.D - df['shortage']
    df[col] = np.sum(df[to_add[i]].values.tolist(),axis=1) - df['shortage']
    # same as : df.loc[df.D < 0, 'D'] = 0
    df.loc[df[col] < 0, col] = 0

for col in ['A1', 'B1', 'C1', 'D1']:
    df.loc[df[col] != 0, col] = df.loc[df[col] != 0, 'remaining']

df = df.drop('shortage', axis=1)