如何在python中获得列作为行组合?
我有以下格式的数据帧:如何在python中获得列作为行组合?,python,pandas,Python,Pandas,我有以下格式的数据帧: country region max min A R1 141 86 A R2 215 72 A R3 473 36 B R1 384 79 B R2 439 88 B R3 172 54 我正在尝试将上面的df转换为下面的输出,逻辑如下 对于A,如果第一个选项是“最大放置最大测量”,则剩余所有最小值 对于A以外的其他选项,如果第二个选项
country region max min
A R1 141 86
A R2 215 72
A R3 473 36
B R1 384 79
B R2 439 88
B R3 172 54
我正在尝试将上面的df转换为下面的输出,逻辑如下
对于A,如果第一个选项是“最大放置最大测量”,则剩余所有最小值
对于A以外的其他选项,如果第二个选项为“最大”,则输入“最大测量值”,其余为“最小值”
注意:还有其他默认选项(最小值)
country region measure Option1 Option2
A R1 86 min min
A R2 72 min min
A R3 36 min min
A R1 86 min max
A R2 72 min max
A R3 36 min max
A R1 86 min default
A R2 72 min default
A R3 36 min default
A R1 86 default min
A R2 72 default min
A R3 36 default min
A R1 86 default default
A R2 72 default default
A R3 36 default default
A R1 86 default max
A R2 72 default max
A R3 36 default max
A R1 141 max min
A R2 215 max min
A R3 473 max min
A R1 141 max default
A R2 215 max default
A R3 473 max default
A R1 141 max max
A R2 215 max max
A R3 473 max max
B R1 79 min min
B R2 88 min min
B R3 54 min min
B R1 384 min max
B R2 439 min max
B R3 172 min max
B R1 79 min default
B R2 88 min default
B R3 54 min default
B R1 79 default min
B R2 88 default min
B R3 54 default min
B R1 79 default default
B R2 88 default default
B R3 54 default default
B R1 384 default max
B R2 439 default max
B R3 172 default max
B R1 79 max min
B R2 88 max min
B R3 54 max min
B R1 79 max default
B R2 88 max default
B R3 54 max default
B R1 384 max max
B R2 439 max max
B R3 172 max max
我知道有一些技巧的熔化选项可以在这里工作,但作为一个新手,无法正确地构建它
请帮忙
编辑1:
使用以下代码实现:
有人能帮我调整一下,提高性能吗
d1 = pd.melt(data, id_vars=['country','region'], value_vars=['max', 'min','default']).sort(['country','region']).reset_index(drop=True)
for ridx,i in enumerate(d1['value']):
if pd.isnull(i):
d1['value'].loc[ridx] = d1['value'].loc[ridx-1]
else:
pass
d2 = d1
from pandas import DataFrame, merge
d1['key'] = 1
d2['key'] = 1
d3 = merge(d1, d2, on='key')
d3 = d3.drop(['key'],axis=1)
for index, row in d3.iterrows():
if d3['region_x'].loc[index] == d3['region_y'].loc[index] and d3['country_x'].loc[index] == d3['country_y'].loc[index]:
pass
else:
d3 = d3.drop([index])
d3 = d3.reset_index(drop=True)
d3['rate'] = ""
for index, row in d3.iterrows():
if d3['country_x'].loc[index] == 'A':
d3['rate'].loc[index] = d3['value_x'].loc[index]
else:
d3['rate'].loc[index] = d3['value_y'].loc[index]
d3 = d3.drop(['value_x','country_y','region_y','value_y'],axis=1)
d3.columns = ['country','region','Option1','Option2','measure']
d3 = d3[['country','region','measure','Option1','Option2']]
关于,您可以与和一起使用:
计时:
data1 = data.copy()
def old(data):
d1 = pd.melt(data, id_vars=['country','region'], value_vars=['max', 'min','default']).sort_values(['country','region']).reset_index(drop=True)
for ridx,i in enumerate(d1['value']):
if pd.isnull(i):
d1['value'].loc[ridx] = d1['value'].loc[ridx-1]
else:
pass
d2 = d1
d1['key'] = 1
d2['key'] = 1
d3 = pd.merge(d1, d2, on='key')
d3 = d3.drop(['key'],axis=1)
for index, row in d3.iterrows():
if d3['region_x'].loc[index] == d3['region_y'].loc[index] and d3['country_x'].loc[index] == d3['country_y'].loc[index]:
pass
else:
d3 = d3.drop([index])
d3 = d3.reset_index(drop=True)
d3['rate'] = ""
for index, row in d3.iterrows():
if d3['country_x'].loc[index] == 'A':
d3['rate'].loc[index] = d3['value_x'].loc[index]
else:
d3['rate'].loc[index] = d3['value_y'].loc[index]
d3 = d3.drop(['value_x','country_y','region_y','value_y'],axis=1)
d3.columns = ['country','region','Option1','Option2','measure']
d3 = d3[['country','region','measure','Option1','Option2']]
return d3
新的解决方案快了300倍,主要是因为没有循环iterrows()
代码:
data1 = data.copy()
def old(data):
d1 = pd.melt(data, id_vars=['country','region'], value_vars=['max', 'min','default']).sort_values(['country','region']).reset_index(drop=True)
for ridx,i in enumerate(d1['value']):
if pd.isnull(i):
d1['value'].loc[ridx] = d1['value'].loc[ridx-1]
else:
pass
d2 = d1
d1['key'] = 1
d2['key'] = 1
d3 = pd.merge(d1, d2, on='key')
d3 = d3.drop(['key'],axis=1)
for index, row in d3.iterrows():
if d3['region_x'].loc[index] == d3['region_y'].loc[index] and d3['country_x'].loc[index] == d3['country_y'].loc[index]:
pass
else:
d3 = d3.drop([index])
d3 = d3.reset_index(drop=True)
d3['rate'] = ""
for index, row in d3.iterrows():
if d3['country_x'].loc[index] == 'A':
d3['rate'].loc[index] = d3['value_x'].loc[index]
else:
d3['rate'].loc[index] = d3['value_y'].loc[index]
d3 = d3.drop(['value_x','country_y','region_y','value_y'],axis=1)
d3.columns = ['country','region','Option1','Option2','measure']
d3 = d3[['country','region','measure','Option1','Option2']]
return d3
谢谢你,耶斯雷尔。我会检查并让你知道。我这边的一个问题是,有没有一种聪明的方法来获取我们正在使用的语句d1['value']=d1['value'].fillna(method='ffill')中的前二个值?这是因为排序顺序会干扰我的最终数据。是的,在
melt
adddata['default']=data['min']
然后删除fillna
。然后解决方案更快-在[73]:%timeit new(data1)100个循环,最好是每个循环3:8.06毫秒
如果我将列排序为d3=d3。排序(['country'、'Option1'、'Option2'、'region'])我以升序获得选项。但我正在寻找具体的最小顺序(所有组合)、最大顺序(全部)和默认顺序。这可能吗?很难回答,对不起。也许你可以提出新的问题。不要忘记添加示例数据、您尝试的内容(d3=d3.sort(['country'、'Option1'、'Option2'、'region'])和所需的输出。可以吗?
data1 = data.copy()
def old(data):
d1 = pd.melt(data, id_vars=['country','region'], value_vars=['max', 'min','default']).sort_values(['country','region']).reset_index(drop=True)
for ridx,i in enumerate(d1['value']):
if pd.isnull(i):
d1['value'].loc[ridx] = d1['value'].loc[ridx-1]
else:
pass
d2 = d1
d1['key'] = 1
d2['key'] = 1
d3 = pd.merge(d1, d2, on='key')
d3 = d3.drop(['key'],axis=1)
for index, row in d3.iterrows():
if d3['region_x'].loc[index] == d3['region_y'].loc[index] and d3['country_x'].loc[index] == d3['country_y'].loc[index]:
pass
else:
d3 = d3.drop([index])
d3 = d3.reset_index(drop=True)
d3['rate'] = ""
for index, row in d3.iterrows():
if d3['country_x'].loc[index] == 'A':
d3['rate'].loc[index] = d3['value_x'].loc[index]
else:
d3['rate'].loc[index] = d3['value_y'].loc[index]
d3 = d3.drop(['value_x','country_y','region_y','value_y'],axis=1)
d3.columns = ['country','region','Option1','Option2','measure']
d3 = d3[['country','region','measure','Option1','Option2']]
return d3
def new(data):
d1 = pd.melt(data, id_vars=['country','region'], value_vars=['max', 'min','default']).sort_values(['country','region']).reset_index(drop=True)
#fill NaN in column value method ffill (propagate last valid observation forward to next valid)
d1['value'] = d1['value'].fillna(method='ffill')
d1['key'] = 1
#you can use double d1
d3 = pd.merge(d1, d1, on='key')
d3 = d3.drop(['key'],axis=1)
#filter columns by conditions - boolean indexing
d3 = d3[(d3['region_x'] == d3['region_y']) & (d3['country_x'] == d3['country_y'])].reset_index(drop=True)
#if condition is true get value_x else value_y
#if neccesarry, convert to int by astype(int)
d3['rate'] = np.where(np.in1d(d3['country_x'], 'A'), d3['value_x'],d3['value_y']).astype(int)
d3 = d3.drop(['value_x','country_y','region_y','value_y'],axis=1)
d3.columns = ['country','region','Option1','Option2','measure']
d3 = d3[['country','region','measure','Option1','Option2']]
return d3
print old(data)
print new(data1)
print (new(data1) == old(data)).all()
country True
region True
measure True
Option1 True
Option2 True
dtype: bool