操作

2016-11-04 10 views
2

私はマルチインデックスデータフレームでの作業と私は苦労していますいくつかの操作をしたいのです:操作

A)私はのために使用しなくても、リスト(要素単位)にいくつかの操作を適用したいと思いますループ

b)は、私は私のデータフレームのインデックスの値を抽出し、それらの値を比較したいと思います。それらは

Cを整数または浮動するオブジェクトから変換されなければならない)私は、forループを使用せず(データフレーム内の値を比較する前に)、その比較

=の値に応じて、列のいずれかの値を選択========================================== ===================== a)のための

import pandas as pd 
import numpy as np 

idx = pd.IndexSlice 
ix = pd.MultiIndex.from_product(
    [['2015', '2016', '2017', '2018'], 
    ['2016', '2017', '2018', '2019', '2020'], 
    ['A', 'B', 'C']], 
    names=['SimulationStart', 'ProjectionPeriod', 'Group'] 
) 

df = pd.DataFrame(np.random.randn(60, 1), index=ix, columns=['Origin']) 
origin = df.loc[idx[:, :, :], 'Origin'].values 

increase_over_base_percent = 0.3 
increase_over_base_abs = 10 
abs_level = 1 
min_increase = 0.001 

'Is there a way to do this comparison without using for loops?' 
# The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 
change = pd.Series(np.nan) 
i = 0 
for element in origin: 
    change[i] = max(
     min(element * (1 + increase_over_base_percent), 
      element + increase_over_base_abs, 
      abs_level), 
     element + min_increase) 
    i += 1 

print(change) 


# Write results to a new column in the DataFrame ('Change') 
df.loc[idx[:, :, :], 'Change'] = change 

# Add data on 'Group' level 
group_qualifier = [0, 0, 1] 

# Is there a way to apply the group_qualifier to the group level without having to slice each index? 
# Note: the formula does not work yet (results are to be reported in a new column of the DataFrame) 
df.loc[idx[:], 'GroupQA'] = group_qualifier 

'This is the part I am struggling with most (my index values are objects, not integers or floats;' 
'and the comparison of values within the DataFrame does not work either)' 
# Create new column 'Selected'; use origin values for all combinations where 
# projectionPeriod < simulationStart & group_qualifier value == 0; 
# use change values for all other combinations 
values = df.index.get_level_values 
mask = (values('ProjectionPeriod') - values('SimulationStart')) <= 1 
mask = mask * df.loc[idx[:], 'GroupQA'].values 
selected = df.loc[mask] 
df.loc[idx[:, :, :], 'Selected'] = selected 
+0

(A)については、私はあなたが避けたいループのために表示されません。 – IanS

+0

@IanS - 混乱のため申し訳ありません。私が話していたforループを反映するようにコードを編集しました。 – Andreas

+0

私の答えを受け入れてくれてありがとう。あなたは他のアイテムに助けが必要でしょうか? – IanS

答えて

2

部分的な答え:

df['Change'] = pd.concat([ 
    pd.concat([ 
     df.loc[:, 'Origin'] * (1 + increase_over_base_percent), 
     df.loc[:, 'Origin'] + increase_over_base_abs, 
    ], axis=1).min(axis=1).clip(upper=abs_level), 
    df.loc[:, 'Origin'] + min_increase 
], axis=1).max(axis=1) 

はアイデアが私たちにあります電子パンダminと(abs_levelためclip使用して少しひねりを加えた、)Originシリーズに直接max機能。

パンダの操作は、インデックスを維持しているので、あなたは直接列に結果を割り当てることができます。


編集:あなたが希望する場合、あなたはcombineアプローチがthis questionの最後で説明し使用することができます。