Python 巨蟒熊猫:如何同时设置2列?

Python 巨蟒熊猫:如何同时设置2列?,python,pandas,Python,Pandas,我发布了一些更简单的内容,因为我认为这很容易理解,但参考您的评论,我错了,所以我编辑了这个问题: 这是代码。我想做它没有一个循环,它应该做在熊猫 import pandas as pd myval = [0.0,1.1, 2.2, 3.3, 4.4, 5.5,6.6, 7.7, 8.8,9.9] s1 = [0,0,1,1,0,0,1,1,0,1] s2 = [0,0,1,0,1,0,1,0,1,1] posin = [10,0,0,0,0,0,0,0,0,0] posout = [0,

我发布了一些更简单的内容,因为我认为这很容易理解,但参考您的评论,我错了,所以我编辑了这个问题:

这是代码。我想做它没有一个循环,它应该做在熊猫

import pandas as pd

myval = [0.0,1.1, 2.2, 3.3, 4.4, 5.5,6.6, 7.7, 8.8,9.9]
s1 = [0,0,1,1,0,0,1,1,0,1]
s2 = [0,0,1,0,1,0,1,0,1,1] 

posin = [10,0,0,0,0,0,0,0,0,0] 
posout = [0,0,0,0,0,0,0,0,0,0]
sig = ['-']

d = {'myval' : myval, 's1' : s1, 's2' : s2}

d = pd.DataFrame(d)

'''
normaly the dataframe should be with the 6 col,
but I can't make the part below working in the df.(THAT is the problem !!)
The real df is 5000+ row, and this should be done for 100+ sets of values,
so this way is not eligible. Too slow.
'''

for i in xrange(1,len(myval)) :
    if (s1[i]== 1) & (s2[i] == 1) & (posin[i-1] != 0 ) :
        posin[i]= 0
        posout[i]= posin[i-1] / myval[i]
        sig.append( 'a')
    elif (s1[i] == 0) & (s2[i] == 1) & (posin[i-1] == 0) :
        posin[i]= posout[i-1] * myval[i]
        posout[i] = 0
        sig.append( 'v')
    else :
        posin[i] =  posin[i-1]
        posout[i] = posout[i-1]
        sig.append('-')

d2 = pd.DataFrame({'posin' : posin , 'posout' : posout , 'sig' : sig })

d = d.join(d2)

#the result wanted :

print d

    myval  s1  s2  posin     posout    sig
0    0.0   0   0  10.000000  0.000000   -
1    1.1   0   0  10.000000  0.000000   -
2    2.2   1   1   0.000000  4.545455   a
3    3.3   1   0   0.000000  4.545455   -
4    4.4   0   1  20.000000  0.000000   v
5    5.5   0   0  20.000000  0.000000   -
6    6.6   1   1   0.000000  3.030303   a
7    7.7   1   0   0.000000  3.030303   -
8    8.8   0   1  26.666667  0.000000   v
9    9.9   1   1   0.000000  2.693603   a
有什么帮助吗


谢谢你

我希望下面的方法可能会奏效(如评论中所建议的),但是(令人惊讶的是?)这种使用np.where会产生一个
值错误:形状不匹配:对象不能广播到单个形状(使用1D从2D中选择):


作为使用where的替代方案,我将分阶段构建:

res = pd.DataFrame({"bin": 0, "bout": df.bin.diff() / df.myval})
res.update(pd.DataFrame({"bin": df.bout.diff() * df.myval,
                         "bout": 0}).loc[(df.s1 == 1) & (df.s2 == 0)])
res.update(pd.DataFrame({"bin": df.bin.diff(),
                         "bout": df.bout.diff()}).loc[(df.s1 == 0) & (df.s2 == 0)])
然后您可以将其分配给df中的两列:

df[["bin", "bout"]] = res

代码参考安迪·海登的答案:

import pandas as pd

myval = [0.0,1.1, 2.2, 3.3, 4.4, 5.5,6.6, 7.7, 8.8,9.9]
s1 = [0,0,1,1,0,0,1,1,0,1]
s2 = [0,0,1,0,1,0,1,0,1,1] 

posin = [10,0,0,0,0,0,0,0,0,0] 
posout = [0,0,0,0,0,0,0,0,0,0]
sig = ['-']

d = {'myval' : myval, 's1' : s1, 's2' : s2,'posin' : posin , 'posout' : posout   }

d = pd.DataFrame(d)

res = pd.DataFrame({"posin": 10, 'sig' : '-', "posout": d.posin.diff() / d.myval})

res.update(pd.DataFrame({"posin": 0,
                         'sig' : 'a',
                         "posout":d.posin.diff() / d.myval }
                         ).loc[(d.s1 == 1) & (d.s2 == 1) & (d.posin.diff() != 0)  ])

res.update(pd.DataFrame({"posin": d.posout.diff() * d.myval,
                         'sig' : 'v',
                         "posout": 0}
                         ).loc[(d.s1 == 0) & (d.s2 == 1) & (d.posin.diff()) == 0])


d[["posin", "posout", 'sig']] = res

print d

   myval  posin  posout  s1  s2 sig
0    0.0     10       0   0   0   v
1    1.1      0       0   0   0   v
2    2.2      0       0   1   1   v
3    3.3      0       0   1   0   v
4    4.4      0       0   0   1   v
5    5.5      0       0   0   0   v
6    6.6      0       0   1   1   v
7    7.7      0       0   1   0   v
8    8.8      0       0   0   1   v
9    9.9      0       0   1   1   v

性能是一个问题吗?否则,只需在帧的索引上循环…是的,我已经用循环完成了,但它非常缓慢…你能发布原始输入数据和期望的输出吗,感谢基本上你的提问可以通过使用3个
loc
语句或一组嵌套的
np语句来完成。其中
语句最好显示真实的输入数据和所需的输出数据我已经编辑了问题,并更改了bin:-(还有posin和posout的bout var name。谢谢你的回答。谢谢你的回答,但在我编辑了这个问题之后,它似乎没有给出结果。我的代码在下面的答案中。@BPulsart因为你发现最好提供一个示例数据框、你尝试的代码示例和期望的结果。Andy,我认为没有这段代码中的问题是没有if/elif/else,所以它先进行第一次更新,然后进行第二次更新,因为一行的结果取决于前一行,所以它不起作用。elif/else是用loc/update完成的,因为这些情况是不同的。我不明白……它与代码上方显示的结果不匹配。顶部的代码是good,但太慢了。最初(当你发布时)没有代码,我不太遵循示例,但我的回答中的策略应该有效。或者问题是这是一个“滚动”式的问题,在这种情况下,你可能需要获得性能。@Andy:好的,在Pandas中这样做似乎不可能(至少我没有解决方案),所以我必须和Cython一起加快速度。谢谢你的帮助。
import pandas as pd

myval = [0.0,1.1, 2.2, 3.3, 4.4, 5.5,6.6, 7.7, 8.8,9.9]
s1 = [0,0,1,1,0,0,1,1,0,1]
s2 = [0,0,1,0,1,0,1,0,1,1] 

posin = [10,0,0,0,0,0,0,0,0,0] 
posout = [0,0,0,0,0,0,0,0,0,0]
sig = ['-']

d = {'myval' : myval, 's1' : s1, 's2' : s2,'posin' : posin , 'posout' : posout   }

d = pd.DataFrame(d)

res = pd.DataFrame({"posin": 10, 'sig' : '-', "posout": d.posin.diff() / d.myval})

res.update(pd.DataFrame({"posin": 0,
                         'sig' : 'a',
                         "posout":d.posin.diff() / d.myval }
                         ).loc[(d.s1 == 1) & (d.s2 == 1) & (d.posin.diff() != 0)  ])

res.update(pd.DataFrame({"posin": d.posout.diff() * d.myval,
                         'sig' : 'v',
                         "posout": 0}
                         ).loc[(d.s1 == 0) & (d.s2 == 1) & (d.posin.diff()) == 0])


d[["posin", "posout", 'sig']] = res

print d

   myval  posin  posout  s1  s2 sig
0    0.0     10       0   0   0   v
1    1.1      0       0   0   0   v
2    2.2      0       0   1   1   v
3    3.3      0       0   1   0   v
4    4.4      0       0   0   1   v
5    5.5      0       0   0   0   v
6    6.6      0       0   1   1   v
7    7.7      0       0   1   0   v
8    8.8      0       0   0   1   v
9    9.9      0       0   1   1   v