Python熊猫:宽格式到长格式,但不同-类似于反向伪列
Sum_值是CS和SC特定组合的所有值的总和 我花了1.5天,无法转换它。使用了stack、transpose和groupby,但没有任何效果。10天前开始编码,刚开始编码,请帮助。请看图片,我无法在文本区域正确粘贴表格Python熊猫:宽格式到长格式,但不同-类似于反向伪列,python,pandas,stack,Python,Pandas,Stack,Sum_值是CS和SC特定组合的所有值的总和 我花了1.5天,无法转换它。使用了stack、transpose和groupby,但没有任何效果。10天前开始编码,刚开始编码,请帮助。请看图片,我无法在文本区域正确粘贴表格 好的,你可以这样做: df = pd.DataFrame({'Product':['R123','R234'], 'Price':[1.18,0.23], 'CS_Medium':[
好的,你可以这样做:
df = pd.DataFrame({'Product':['R123','R234'],
'Price':[1.18,0.23],
'CS_Medium':[.15, np.nan],
'CS_Small':[np.nan, -0.03],
'SC_A':[np.nan,0.04],
'SC_B':[np.nan,np.nan],
'SC_C':[0.38,0.05]})
df.columns = df.columns.str.split('_').str[-1]
(df.melt(['Product','Medium','Small','Price'],value_name='Values_1', var_name='SC')
.melt(['Product','SC','Price','Values_1'],value_name='Values_2',var_name='CS')
.set_index(['Product','CS','SC','Price'])
.sum(axis=1)
.reset_index(name='SUM_Values')
.sort_values(by=['Product','CS','SC']))
输出:
Product CS SC Price SUM_values
0 R123 Medium A 1.18 0.15
2 R123 Medium B 1.18 0.15
4 R123 Medium C 1.18 0.53
6 R123 Small A 1.18 NaN
8 R123 Small B 1.18 NaN
10 R123 Small C 1.18 0.38
1 R234 Medium A 0.23 0.04
3 R234 Medium B 0.23 NaN
5 R234 Medium C 0.23 0.05
7 R234 Small A 0.23 0.01
9 R234 Small B 0.23 -0.03
11 R234 Small C 0.23 0.02
好的,你可以这样做:
df = pd.DataFrame({'Product':['R123','R234'],
'Price':[1.18,0.23],
'CS_Medium':[.15, np.nan],
'CS_Small':[np.nan, -0.03],
'SC_A':[np.nan,0.04],
'SC_B':[np.nan,np.nan],
'SC_C':[0.38,0.05]})
df.columns = df.columns.str.split('_').str[-1]
(df.melt(['Product','Medium','Small','Price'],value_name='Values_1', var_name='SC')
.melt(['Product','SC','Price','Values_1'],value_name='Values_2',var_name='CS')
.set_index(['Product','CS','SC','Price'])
.sum(axis=1)
.reset_index(name='SUM_Values')
.sort_values(by=['Product','CS','SC']))
输出:
Product CS SC Price SUM_values
0 R123 Medium A 1.18 0.15
2 R123 Medium B 1.18 0.15
4 R123 Medium C 1.18 0.53
6 R123 Small A 1.18 NaN
8 R123 Small B 1.18 NaN
10 R123 Small C 1.18 0.38
1 R234 Medium A 0.23 0.04
3 R234 Medium B 0.23 NaN
5 R234 Medium C 0.23 0.05
7 R234 Small A 0.23 0.01
9 R234 Small B 0.23 -0.03
11 R234 Small C 0.23 0.02
我用的是从宽到长
详细信息:
v1
Out[38]:
SCKey SC
Product Price
R123 1.18 A NaN
1.18 B NaN
1.18 C 0.38
R234 0.23 A 0.04
0.23 B NaN
0.23 C 0.05
v2
Out[39]:
CSKey CS
Product Price
R123 1.18 Medium 0.15
1.18 Small NaN
R234 0.23 Medium NaN
0.23 Small -0.03
我用的是从宽到长
详细信息:
v1
Out[38]:
SCKey SC
Product Price
R123 1.18 A NaN
1.18 B NaN
1.18 C 0.38
R234 0.23 A 0.04
0.23 B NaN
0.23 C 0.05
v2
Out[39]:
CSKey CS
Product Price
R123 1.18 Medium 0.15
1.18 Small NaN
R234 0.23 Medium NaN
0.23 Small -0.03
选择1
不太明显,但没有硬编码值
from itertools import product
d_ = df.set_index('Product')
prc = d_.pop('Price')
d_.columns = d_.columns.str.split('_', expand=True)
c = d_.columns
l0 = c.levels[0]
l1 = c.levels[1]
b0 = c.labels[0]
b1 = c.labels[1]
r0 = range(len(l0))
ptups = list(product(*(l1[b1][b0 == i] for i in r0)))
midx = pd.MultiIndex.from_tuples(
[(x,) + t for x in l0 for t in ptups],
names=['key'] + l0.tolist()
)
n = midx.nlevels
_d = d_[[(x0, x1) for x0, y1 in zip(l0, zip(*ptups)) for x1 in y1]]
_d.columns = midx
_d = _d.stack(list(range(1, n)), dropna=False)
_d.fillna(0).sum(1).where(_d.notna().any(1)).reset_index(name='SUM_values')
Product CS SC SUM_values
0 R123 Medium A 0.15
1 R123 Medium B 0.15
2 R123 Medium C 0.53
3 R123 Small A NaN
4 R123 Small B NaN
5 R123 Small C 0.38
6 R234 Medium A 0.04
7 R234 Medium B NaN
8 R234 Medium C 0.05
9 R234 Small A 0.01
10 R234 Small B -0.03
11 R234 Small C 0.02
选择2
使用defaultdict和for循环
选择3
使用defaultdict、itertools.product和lookup
选择1
不太明显,但没有硬编码值
from itertools import product
d_ = df.set_index('Product')
prc = d_.pop('Price')
d_.columns = d_.columns.str.split('_', expand=True)
c = d_.columns
l0 = c.levels[0]
l1 = c.levels[1]
b0 = c.labels[0]
b1 = c.labels[1]
r0 = range(len(l0))
ptups = list(product(*(l1[b1][b0 == i] for i in r0)))
midx = pd.MultiIndex.from_tuples(
[(x,) + t for x in l0 for t in ptups],
names=['key'] + l0.tolist()
)
n = midx.nlevels
_d = d_[[(x0, x1) for x0, y1 in zip(l0, zip(*ptups)) for x1 in y1]]
_d.columns = midx
_d = _d.stack(list(range(1, n)), dropna=False)
_d.fillna(0).sum(1).where(_d.notna().any(1)).reset_index(name='SUM_values')
Product CS SC SUM_values
0 R123 Medium A 0.15
1 R123 Medium B 0.15
2 R123 Medium C 0.53
3 R123 Small A NaN
4 R123 Small B NaN
5 R123 Small C 0.38
6 R234 Medium A 0.04
7 R234 Medium B NaN
8 R234 Medium C 0.05
9 R234 Small A 0.01
10 R234 Small B -0.03
11 R234 Small C 0.02
选择2
使用defaultdict和for循环
选择3
使用defaultdict、itertools.product和lookup
我知道你不能在帖子中包含数据的原因吗?在链接和图片中添加了数据,我不知道如何将其作为文本包含。感谢PiRSquared、Scott和Wen的回答。如何实现自动化,而不是硬编码列名。唯一硬编码的名称是SUM_值。这个转换是一个自动化的长过程的一部分,我没有机会看到列的名称。我唯一知道的是,在输入表中,列名用列级分隔列名。例如,在SC_A、SC_B中;我知道前面是列名SC,下划线后面是列级别A、B和C。我已经用一个通用的解决方案更新了我的帖子。我知道你不能在帖子中包含数据的原因吗?在链接和图片中添加了数据,我不知道如何作为文本包含。感谢PiRSquared、Scott和Wen的回答。如何实现自动化,而不是硬编码列名。唯一硬编码的名称是SUM_值。这个转换是一个自动化的长过程的一部分,我没有机会看到列的名称。我唯一知道的是,在输入表中,列名用列级分隔列名。例如,在SC_A、SC_B中;我知道前面是列名SC,下划线后面是列级别A、B和C。我已经用一个通用解决方案更新了我的帖子。对于r0中的I,ptups=listproduct*l1[b1][b0==I]。在选项1中,上面的行显示产品的获取错误。错误是产品未定义。我尝试将产品定义为元组,但没有成功。很抱歉,我忘记了导入。没问题,这非常有用,现在一切都正常,将扩展到30-40列。这里唯一的变化是我将_d.notna替换为_d.notnull。完成此更改是因为我获取了错误AttributeError:“DataFrame”对象没有属性“notna”。感谢您的帮助。对于r0中的i,ptups=listproduct*l1[b1][b0==i]。在选项1中,上面的行显示产品的获取错误。错误是产品未定义。我尝试将产品定义为元组,但没有成功。很抱歉,我忘记了导入。没问题,这非常有用,现在一切都正常,将扩展到30-40列。这里唯一的变化是我将_d.notna替换为_d.notnull。完成此更改是因为我获取了错误AttributeError:“DataFrame”对象没有属性“notna”。谢谢你的帮助。
from itertools import product
from collections import defaultdict
d = defaultdict(list)
for c in df.columns:
k, *v = c.split('_')
if v:
d[k].append(v[0])
d = {**df[['Product']].to_dict('l'), **d}
d_ = df.set_index('Product')
ndf = pd.DataFrame(dict(zip(d.keys(), zip(*product(*d.values())))))
cs = pd.Series(d_.lookup(ndf.Product, ndf.CS.radd('CS_')), ndf.index)
sc = pd.Series(d_.lookup(ndf.Product, ndf.SC.radd('SC_')), ndf.index)
ndf['SUM_values'] = cs.add(sc, fill_value=0)
ndf[['Product', 'CS', 'SC', 'SUM_values']]
Product CS SC SUM_values
0 R123 Medium A 0.15
1 R123 Medium B 0.15
2 R123 Medium C 0.53
3 R123 Small A NaN
4 R123 Small B NaN
5 R123 Small C 0.38
6 R234 Medium A 0.04
7 R234 Medium B NaN
8 R234 Medium C 0.05
9 R234 Small A 0.01
10 R234 Small B -0.03
11 R234 Small C 0.02