Новые pandas столбцы, основанные на других столбцах, в зависимости от значения другого столбца - PullRequest
0 голосов
/ 26 апреля 2020

Извините за заголовок, который, возможно, более сложен, чем сама проблема;)

У меня есть следующий pandas dataframe

    grh  anc     anc1     anc2    anc3     anc4     anc5    anc6     anc7  
1     2    5  0.10000  0.12000  0.1800  0.14000  0.15000  0.1900  0.20000   
2     3    7  0.03299  0.05081  0.0355  0.02884  0.03054  0.0332  0.03115   
3     4    3  0.00000  0.00000  0.0000  0.00000  0.00000  0.0000  0.00000   
4     5    4  0.00000  0.00000  0.0000  0.00000  0.00000  0.0000  0.00000   
5     6    1  0.10000  0.10000  0.1000  0.10000  0.10000  0.1000  0.10000   


       anc8     anc9    anc10  
1   0.10000  0.21000  0.24000  
2   0.02177  0.04903  0.04399  
3   0.00000  0.00000  0.00000  
4   0.00000  0.00000  0.00000  
5   0.10000  0.10000  0.10000  

Я хотел бы добавить новые столбцы с forl oop lap1, lap2, .... в зависимости от значений переменной an c. Например, в первом ряду anc = 5, поэтому lap1 должен быть равен значению anc5 (0.1500) , lap2 равно anc6 (0.1900) ... во втором строка lap1 = anc7 (0.03115) , lap2 = anc8 (0.02177) , ...

Итак, вывод должен выглядеть как

grh anc anc1    anc2    anc3    anc4    anc5    anc6    anc7    anc8    anc9    anc10   lap1    lap2    lap3
2   5   0.10000 0.12000 0.18000 0.14000 0.15000 0.19000 0.20000 0.1000  0.21000 0.24000 0.15000 0.19000 0.20000
3   7   0.03299 0.05081 0.0355  0.02884 0.03054 0.0332  0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903
4   3   0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
5   4   0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
6   1   0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000

Я попробовал что-то очень простое c, но, похоже, не работает

for i in range(1,4):
    j=df['anc']+i
    df['lap'+str(i)]= df['anc'+str(j)]

Я был бы очень признателен, если у вас есть идея. Thks

Ответы [ 3 ]

1 голос
/ 26 апреля 2020

установите grh & anc в качестве индекса, поскольку мы ищем индекс в столбцах anc[1-9]. Это также удобно, когда мы записываем выходные столбцы:

df2 = df.set_index(['grh', 'anc']) 

для каждого среза строки в столбцы, используя значение anc, которое теперь находится в индексе, принимая 3 смежных значения, преобразуем их для серии с именами, как вы ожидаете в выходных данных, и назначьте их соответствующим выходным столбцам

outcols = ['lap1', 'lap2', 'lap3']
df2[outcols] = df2.apply(lambda x: pd.Series(x[x.name[1]-1:x.name[1]+2].values, index=outcols), axis=1)

df2 выглядит следующим образом:

            anc1     anc2    anc3     anc4     anc5    anc6     anc7     anc8     anc9    anc10     lap1     lap2     lap3
grh anc
2   5    0.10000  0.12000  0.1800  0.14000  0.15000  0.1900  0.20000  0.10000  0.21000  0.24000  0.15000  0.19000  0.20000
3   7    0.03299  0.05081  0.0355  0.02884  0.03054  0.0332  0.03115  0.02177  0.04903  0.04399  0.03115  0.02177  0.04903
4   3    0.00000  0.00000  0.0000  0.00000  0.00000  0.0000  0.00000  0.00000  0.00000  0.00000  0.00000  0.00000  0.00000
5   4    0.00000  0.00000  0.0000  0.00000  0.00000  0.0000  0.00000  0.00000  0.00000  0.00000  0.00000  0.00000  0.00000
6   1    0.10000  0.10000  0.1000  0.10000  0.10000  0.1000  0.10000  0.10000  0.10000  0.10000  0.10000  0.10000  0.10000

сбросьте индекс еще раз, если вы хотите вернуться grh & anc обратно к столбцам.


альтернативный поиск на основе имени вместо позиционного поиска:

определяет вспомогательную функцию для выполнения поиска по столбцу при условии плавающей запятой , Он должен принимать число с плавающей запятой, потому что pandas будет автоматически выгружать int64 в число с плавающей запятой, если ряд содержит какие-либо нецелые значения. Используйте эту функцию, чтобы выполнить поиск и назначить вывод. Одним из преимуществ этого подхода является то, что set_index не требуется.

def cols(n,p): return [f'{p}{i}' for i in range(int(n), int(n+3))] 
df[cols(1, 'lap')] = df.apply(lambda x: pd.Series(x[cols(x.anc, 'anc')].values), axis=1)
0 голосов
/ 26 апреля 2020
# Where is the new lap column starting
startingNewColsNumber  = df.shape[1]

# How many new lap columns to add
numNewCols = df.grh.max() 

# Generate new lap columns
newColNames = ['lap'+str(x) for x in range(1, numNewCols + 1)]

# add new lap columns to the dataframe
for lapName in newColNames:
    df[lapName] = np.NaN

# now fill the values for each of rows for the new 'lap' columns 
for row in df.index:
    startCopyCol = df.loc[row,'anc'] + 1   # What is the begening anc value to start copying
    howmany = df.loc[row,'grh']            # How many lap values should I fill
    df.iloc[row, startingNewColsNumber : startingNewColsNumber + howmany]  =  \
    df.iloc[row, startCopyCol : startCopyCol + howmany].values

df 

Вот вывод, который я получил:

grh anc anc1    anc2    anc3    anc4    anc5    anc6    anc7    anc8    anc9    anc10   lap1    lap2    lap3    lap4    lap5    lap6
0   2   5   0.10000 0.12000 0.1800  0.14000 0.15000 0.1900  0.20000 0.10000 0.21000 0.24000 0.15000 0.19000 NaN NaN NaN NaN
1   3   7   0.03299 0.05081 0.0355  0.02884 0.03054 0.0332  0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903 NaN NaN NaN
2   4   3   0.00000 0.00000 0.0000  0.00000 0.00000 0.0000  0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.0 NaN NaN
3   5   4   0.00000 0.00000 0.0000  0.00000 0.00000 0.0000  0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.0 0.0 NaN
4   6   1   0.10000 0.10000 0.1000  0.10000 0.10000 0.1000  0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.1 0.1 0.1

Дайте мне знать, если это даст какое-то решение, которое вы ищете

0 голосов
/ 26 апреля 2020

Немного "грубой силы", но я не понимаю, как вы можете сделать это иначе:

df[[f"lap{i}" for i in range(1,4)]]= \
    df.apply(lambda x: \
        pd.Series({f"lap{j}": x[f"anc{int(j+x['anc']-1)}"] for j in range(1,4)}) \
    , axis=1)

(Предполагается, что у вас есть максимум lap при 3)

...