Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中获得列作为行组合?_Python_Pandas - Fatal编程技术网

如何在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
add
data['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