Python:如何在多系列数据帧中找到第一个非零值?

时间:2017-11-14 06:22:58

标签: python pandas dataframe

我有一个数据框,其中有5列已编入索引。数据由0&1和1组成。我想在每个系列中找到第一个非零并且将它(并且只有它)乘以100。

Date A B C D E 3/1/16 0 0 0 0 0 3/2/16 0 0 1 0 0 3/3/16 1 0 0 0 0 3/4/16 0 1 0 0 0 3/7/16 0 0 1 0 1 3/8/16 0 0 0 0 1 3/9/16 0 0 0 1 1 我尝试了以下代码,但它没有用。

for col in df.columns:
    idx = df[col].first_valid_index()
    df[col][idx] = df[col][idx]*100.

3 个答案:

答案 0 :(得分:5)

首先对所有数字列使用set_index,然后使用链eq创建cumsum(与==相同)的布尔模板,并进行比较。

然后按掩码和多个选择,最后reset_index

df = df.set_index('Date')

m = df.eq(1) & df.cumsum().eq(1)
df[m] *= 100

df = df.reset_index()
print (df)
     Date    A    B    C    D    E
0  3/1/16    0    0    0    0    0
1  3/2/16    0    0  100    0    0
2  3/3/16  100    0    0    0    0
3  3/4/16    0  100    0    0    0
4  3/7/16    0    0    1    0  100
5  3/8/16    0    0    0    0    1
6  3/9/16    0    0    0  100    1

详细说明:

print (df.cumsum())
        A  B  C  D  E
Date                 
3/1/16  0  0  0  0  0
3/2/16  0  0  1  0  0
3/3/16  1  0  1  0  0
3/4/16  1  1  1  0  0
3/7/16  1  1  2  0  1
3/8/16  1  1  2  0  2
3/9/16  1  1  2  1  3


print (df.cumsum().eq(1))
            A      B      C      D      E
Date                                     
3/1/16  False  False  False  False  False
3/2/16  False  False   True  False  False
3/3/16   True  False   True  False  False
3/4/16   True   True   True  False  False
3/7/16   True   True  False  False   True
3/8/16   True   True  False  False  False
3/9/16   True   True  False   True  False

print (df.eq(1))
            A      B      C      D      E
Date                                     
3/1/16  False  False  False  False  False
3/2/16  False  False   True  False  False
3/3/16   True  False  False  False  False
3/4/16  False   True  False  False  False
3/7/16  False  False   True  False   True
3/8/16  False  False  False  False   True
3/9/16  False  False  False   True   True
m = df.eq(1) & df.cumsum(axis=1).eq(1)
print (m)
            A      B      C      D      E
Date                                     
3/1/16  False  False  False  False  False
3/2/16  False  False   True  False  False
3/3/16   True  False  False  False  False
3/4/16  False   True  False  False  False
3/7/16  False  False   True  False  False
3/8/16  False  False  False  False   True
3/9/16  False  False  False   True  False

设定:

from pandas.compat import StringIO

temp=u"""Date   A   B   C   D   E
3/1/16  0   0   0   0   0
3/2/16  0   0   1   0   0
3/3/16  1   0   0   0   0
3/4/16  0   1   0   0   0
3/7/16  0   0   1   0   1
3/8/16  0   0   0   0   1
3/9/16  0   0   0   1   1"""
df = pd.read_csv(StringIO(temp), sep="\s+")
print (df)

     Date  A  B  C  D  E
0  3/1/16  0  0  0  0  0
1  3/2/16  0  0  1  0  0
2  3/3/16  1  0  0  0  0
3  3/4/16  0  1  0  0  0
4  3/7/16  0  0  1  0  1
5  3/8/16  0  0  0  0  1
6  3/9/16  0  0  0  1  1

答案 1 :(得分:3)

我知道有一种方法可以在这里使用argmax

df = df.set_index('Date')

v = df.values
v[v.argmax(0), np.arange(df.shape[1] - 1)] *= 100  
df[:] = v

df.reset_index()



     Date    A    B    C    D    E
0  3/1/16    0    0    0    0    0
1  3/2/16    0    0  100    0    0
2  3/3/16  100    0    0    0    0
3  3/4/16    0  100    0    0    0
4  3/7/16    0    0  100    0    1
5  3/8/16    0    0    0    0  100
6  3/9/16    0    0    0  100    1

得到here的一点帮助。

答案 2 :(得分:2)

使用for循环,我们可以

cols = df.columns[df.columns != 'Date']
for col in cols:
    idx = df[col][df[col] != 0].index[0]
    df[col][idx] = df[col][idx]*100