2017-04-27 143 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 
相关问题