2017-04-27 146 views
2

我正在很難找到熊貓數據框問題的解決方案。熊貓數據幀 - 按行,有條件地用最後一列值替換多個列值

問題:在pandas數據框中,如果一個單元格等於1,則將其替換爲在數據框的最後一列中找到的單元格值。我已經構建並填充了初始數據框,但尚未能夠進入下一步。

的dataframes:數據幀的一個例子(初始和最終):

Intitial_dataframe:

 fNum 1 2 3 4 5 6 7 labelx 
Index         
1   1 0 1 1 1 0 0 0  2 
2   1 0 0 1 1 0 0 0  2 
4   1 0 0 0 0 0 1 0  3 
5   1 0 0 0 0 0 0 0  0 
6   1 0 0 1 0 0 0 0  3 
7   1 0 0 0 1 0 0 0  3 
1   2 0 1 0 0 0 0 0  2 
2   2 1 1 1 0 0 0 0  2 
3   2 1 1 1 0 0 0 0  2 
4   2 1 1 0 0 0 0 0  2 
5   2 0 0 0 0 1 0 0  0 
6   2 0 0 0 0 1 1 1  3 
7   2 0 0 0 0 1 1 1  3 

Finished_dataframe:

 fNum 1 2 3 4 5 6 7 labelx 
Index          
1   1 0 2 2 2 0 0 0  2 
2   1 0 0 2 2 0 0 0  2 
4   1 0 0 0 0 0 3 0  3 
5   1 0 0 0 0 0 0 0  0 
6   1 0 0 3 0 0 0 0  3 
7   1 0 0 0 3 0 0 0  3 
1   2 0 2 0 0 0 0 0  2 
2   2 2 2 2 0 0 0 0  2 
3   2 2 2 2 0 0 0 0  2 
4   2 2 2 0 0 0 0 0  2 
5   2 0 0 0 0 0 0 0  0 
6   2 0 0 0 0 3 3 3  3 
7   2 0 0 0 0 3 3 3  3 

最新路徑嘗試:

dfIX = Intitial_dataframe.ix[:, 2:8] #<--The "body" of the data 
labelx_frame = Intitial_dataframe.ix[:, 8:9] #<-- The labelx column 
dfIX[dfIX>0] = labelx_frame #<-- Attempt to replace values, nan instead 

這給以前所有1的細胞。

求助真誠請求:
我很新的熊貓和蟒蛇,並花了幾個小時揮舞着關於閱讀過熊貓和數據幀操作無濟於事。任何建議將不勝感激!提前感謝您的時間和幫助。

+3

我們真的不在乎它是否是家庭作業或以其他方式。你已經毫不費力地自己解決這個問題。 – blacksite

+0

您似乎是StackOverflow的新用戶,因此請[參觀](https://stackoverflow.com/tour)本網站。我們不咬人,只要代表你表現出一點努力。 – blacksite

+0

謝謝你在改進我的問題上的幫助。我會繼續努力使其更加連貫和參與。我做了一些編輯。 – stumpedAgain

回答

1

我重新創建了部分數據,因爲輸入數據最初是張貼爲圖片而不是可複製文本。我會留給你,根據你的具體數據調整這種方法。

這是最簡單,無疑是最可讀的方式做到這一點,利用numpy.where

>>> df = pd.DataFrame({1: [0,0,0,1,1,0,0,1,0,1], 2: [1,1,1,1,0,0,0,0,1,0], 3: [1,1,0,1,0,0,0,1,1,0], 'label_x': [2,2,3,0,0,2,3,2,2,2]}) 
>>> df 
    1 2 3 label_x 
0 0 1 1  2 
1 0 1 1  2 
2 0 1 0  3 
3 1 1 1  0 
4 1 0 0  0 
5 0 0 0  2 
6 0 0 0  3 
7 1 0 1  2 
8 0 1 1  2 
9 1 0 0  2 
>>> for c in df: 
...  if c != 'label_x': 
...   df[c] = np.where(df[c] == 1, df['label_x'], df[c]) 
... 
>>> df 
    1 2 3 label_x 
0 0 2 2  2 
1 0 2 2  2 
2 0 3 0  3 
3 0 0 0  0 
4 0 0 0  0 
5 0 0 0  2 
6 0 0 0  3 
7 2 0 2  2 
8 0 2 2  2 
9 2 0 0  2 

這裏的另一種方式做到這一點,但我只提供這是「權力」的一個例子(我不知道這是否是合適的詞...)。實際上,這是我最初解決您的問題的方式,但認爲這僅僅是提供這一點而已。如果我是你,我寧願numpy.where。但是,這只是爲了演示的緣故:

# Here is where we use a dictionary to get the new values from the final column 
>>> new_values = {c: [df.loc[idx, 'label_x'] if val == 1 else val for idx, val in enumerate(df[c])] for c in df[list(filter(lambda x: x != 'label_x', df))]} 
>>> new_values 
{1: [0, 0, 0, 0, 0, 0, 0, 2, 0, 2], 2: [2, 2, 3, 0, 0, 0, 0, 0, 2, 0], 3: [2, 2, 0, 0, 0, 0, 0, 2, 2, 0]} 

# We can just create a new dataframe with the "new" columns made above 
# and the original label_x column 
>>> new_df = pd.DataFrame({**new_values, **{'label_x': df['label_x'].values}}) 
>>> new_df 
    1 2 3 label_x 
0 0 2 2  2 
1 0 2 2  2 
2 0 3 0  3 
3 0 0 0  0 
4 0 0 0  0 
5 0 0 0  2 
6 0 0 0  3 
7 2 0 2  2 
8 0 2 2  2 
9 2 0 0  2 

而且,看看這個!我們得到相同的答案。

欲瞭解更多關於這些**的詳情,請參閱Unpacking generalizations in Python 3。這是合併字典的有效語法。

你也可以考慮這樣做,通過每列的相應列表中new_values基本迭代:

for c in [1,2,3]: 
    df[c] = new_values[c] 

有很多方法對皮膚這隻貓!

+0

謝謝,這似乎是完美的!我一直在圈子裏跑太久。瞭解這兩種解決方案的靈活性是值得讚賞的。對於更大的數據幀,首選方法是哪裏?{9000,600} – stumpedAgain

+0

600列不應該太多。如果速度是一個問題,NumPy通常是首選的解決方案,因爲它大部分是用後端速度更快的C語言編寫的。如果這能解決您的問題,請註冊並接受! – blacksite

0

你也可以用numpy來做到這一點。

df = pd.DataFrame({1: [0,0,0,1,1,0,0,1,0,1], 2: [1,1,1,1,0,0,0,0,1,0], 3: [1,1,0,1,0,0,0,1,1,0], 'label_x': [2,2,3,0,0,2,3,2,2,2]}) 

1 2 3 label_x 
0 0 1 1  2 
1 0 1 1  2 
2 0 1 0  3 
3 1 1 1  0 
4 1 0 0  0 
5 0 0 0  2 
6 0 0 0  3 
7 1 0 1  2 
8 0 1 1  2 
9 1 0 0  2 

而且,這

mask = df.values[:, :-1] == 1 
df.values[:, :-1] = np.where(mask, mask * df.values[:, -1:], df.values[:, :-1]) 

產量,

1 2 3 label_x 
0 0 2 2  2 
1 0 2 2  2 
2 0 3 0  3 
3 0 0 0  0 
4 0 0 0  0 
5 0 0 0  2 
6 0 0 0  3 
7 2 0 2  2 
8 0 2 2  2 
9 2 0 0  2 
相關問題