有一个如下所示的数据集:
Date Item A.unit B.Unit C.Unit D.Unit
10/11 A,D 5 0 0 12
11/11 A,B,C 10 10 5 0
12/11 A 20 0 0 0 我想要输出列,这样只要列表中有一个以上的元素,它就会计算单位的差值,当存在单个元素时,它就会显示零。因此,输出将是:
Date Item A.unit B.Unit C.Unit D.Unit output
10/11 A,D 5 0 0 12 5-12=-7
11/11 A,B,C 10 10 5 0 10-10-5=-5
12/11 A 20 0 0 0 0--since only one element is there谁能告诉我如何获得输出列。
发布于 2019-11-20 19:24:12
使用无检查Item列的解决方案-它对每个Unit列使用第一个非0值,并用值的总和减去,如果只有1个值,则设置0
#all columns without first and second
df1 = df.iloc[:, 2:].mask(lambda x: x==0)
#alternative
#all columns with Unit in column names
#df1 = df.filter(like='Unit').mask(lambda x: x==0)
first = df1.bfill(axis=1).iloc[:, 0]
df['output'] = np.where(df1.count(axis=1) == 1, 0, first - df1.sum(axis=1) + first)
print (df)
Date Item A.Unit B.Unit C.Unit D.Unit output
0 10/11 A,D 5 0 0 12 -7.0
1 11/11 A,B,C 10 10 5 0 -5.0
2 12/11 A 20 0 0 0 0.0具有按Item列匹配解决方案-将Item分解为行,如果只有一个值,则按-1和0倍增,最后聚合sum、first和join
df = df.assign(Item = df['Item'].str.split(',')).explode('Item').reset_index(drop=True)
df['new'] = df.lookup(df.index, df['Item'] + '.Unit')
df.loc[df.duplicated(subset=['Date']), 'new'] *= -1
df.loc[~df.duplicated(subset=['Date'], keep=False), 'new'] = 0
d1 = dict.fromkeys(df.columns.difference(['Date','Item','new']), 'first')
fin = {**{'Item':','.join}, **d1, **{'new':'sum'}}
df = df.groupby('Date', as_index=False).agg(fin)
print (df)
Date Item A.Unit B.Unit C.Unit D.Unit new
0 10/11 A,D 5 0 0 12 -7
1 11/11 A,B,C 10 10 5 0 -5
2 12/11 A 20 0 0 0 0发布于 2019-11-20 19:25:14
这里有一个解决方案。第一步是创建一个在特定行上执行所需操作的函数:
from functool import reduce
def sum_function(x):
if len(x[x != 0]) == 1:
return 0
else:
return reduce(lambda a,b: a-b, x)如果行中只有一个元素不为0,则返回0。如果有更多的元素,则将它们全部减去。下面是如何将该函数应用于每一行:
columns = ['A.unit', 'B.unit', 'C.unit', 'D.unit']
df.apply(lambda x: sum_function(x[columns]), axis=1)结果是:
0 -7
1 -5
2 0您可以将其添加为新列:
df['output'] = df.apply(lambda x: sum_function(x[columns]), axis=1)发布于 2019-11-20 19:28:08
尝试:
def calc(row):
out = row[np.argmax(np.array(row.tolist()) > 0)]
for c in row.values[np.argmax(np.array(row.tolist()) > 0)+1:]:
out -= c
if out == row.sum():
return 0
else:
return out
df['output'] = df.drop(['Date','Item'], axis=1).apply(calc, axis=1)输出:
Date Item A.unit B.Unit C.Unit D.Unit output
0 10/11 A,D 5 0 0 12 -7
1 11/11 A,B,C 10 10 5 0 -5
2 12/11 A 20 0 0 0 0https://stackoverflow.com/questions/58953026
复制相似问题