熊猫:类型错误:在日期列上选择时,“int”和“str”实例之间不支持“>”

Pau*_*aul 12 python pandas

我有一个带有时间戳列的 Pandas DataFrame。我可以从此列中选择日期范围。但是在我对 DataFrame 中的其他列进行更改后,我不能再收到错误消息“TypeError: '>' not supported between 'int' 和 'str'”。

下面的代码重现了问题:

  • 生成一个带有一些随机数的 DataFrame
  • 添加带有日期的列
  • 在日期列上选择

    df = pd.DataFrame(np.random.random((200,3)))
    df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
    mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')
    print(df.loc[mask])
    
    Run Code Online (Sandbox Code Playgroud)

都好:

            0         1         2       date
153  0.280575  0.810817  0.534509 2000-06-02
154  0.490319  0.873906  0.465698 2000-06-03
155  0.070790  0.898340  0.390777 2000-06-04
156  0.896007  0.824134  0.134484 2000-06-05
157  0.539633  0.814883  0.976257 2000-06-06
158  0.772454  0.420732  0.499719 2000-06-07
159  0.498020  0.495946  0.546043 2000-06-08
160  0.562385  0.460190  0.480170 2000-06-09
161  0.924412  0.611929  0.459360 2000-06-10
Run Code Online (Sandbox Code Playgroud)

但是,现在我将列 0 设置为 0,如果它超过 0.7 并重复:

df[df[0] > 0.7] = 0
mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

TypeError: '>' not supported between instances of 'int' and 'str'
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况,我该如何避免?

Qua*_*ang 8

您可以将时间戳 ( Timestamp('2000-01-01 00:00:00')) 与字符串进行比较,pandas 会Timestamp为您将字符串转换为。但是一旦将值设置为0,就无法将 anint与 a进行比较str

解决此问题的另一种方法是更改​​操作顺序。

filters = df[0] > 0.7
mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')

df[filters] = 0
print(df.loc[mask & filters])
Run Code Online (Sandbox Code Playgroud)

此外,您提到如果第 0 列超过 0.7,您想将其设置为 0,因此df[df[0]>0.7] = 0并不完全符合您的要求:它将整行设置为0. 反而:

df.loc[df[0] > 0.7, 0] = 0
Run Code Online (Sandbox Code Playgroud)

那么你用原来的面具应该没有任何问题。


jez*_*ael 5

如果检查输出问题是datetimes由 set 设置的0,因为没有指定 set 的列,所以 pandas 设置所有列:

df[df[0] > 0.7] = 0

print (df.head(10))
          0         1         2                 date
0  0.420593  0.519151  0.149883  2000-01-01 00:00:00
1  0.014364  0.503533  0.601206  2000-01-02 00:00:00
2  0.099144  0.090100  0.799383  2000-01-03 00:00:00
3  0.411158  0.144419  0.964909  2000-01-04 00:00:00
4  0.151470  0.424896  0.376281  2000-01-05 00:00:00
5  0.000000  0.000000  0.000000                    0
6  0.292871  0.868168  0.353377  2000-01-07 00:00:00
7  0.536018  0.737273  0.356857  2000-01-08 00:00:00
8  0.364068  0.314311  0.475165  2000-01-09 00:00:00
9  0.000000  0.000000  0.000000                    0
Run Code Online (Sandbox Code Playgroud)

解决方案仅通过以下方式设置数字列DataFrame.select_dtypes

df.loc[df[0] > 0.7, df.select_dtypes(np.number).columns] = 0
#or specify columns by list
#df.loc[df[0] > 0.7, [0,1]] = 0

print (df.head(10))
          0         1         2       date
0  0.416697  0.459268  0.146755 2000-01-01
1  0.645391  0.742737  0.023878 2000-01-02
2  0.000000  0.000000  0.000000 2000-01-03
3  0.456387  0.996946  0.450155 2000-01-04
4  0.000000  0.000000  0.000000 2000-01-05
5  0.000000  0.000000  0.000000 2000-01-06
6  0.265673  0.951874  0.175133 2000-01-07
7  0.434855  0.762386  0.653668 2000-01-08
8  0.000000  0.000000  0.000000 2000-01-09
9  0.000000  0.000000  0.000000 2000-01-10
Run Code Online (Sandbox Code Playgroud)

DatetimeIndex如果所有其他列都是数字,则创建另一个解决方案:

df = df.set_index('date')
df.loc[df[0] > 0.7] = 0

print (df.head(10))
                   0         1         2
date                                    
2000-01-01  0.316875  0.584754  0.925727
2000-01-02  0.000000  0.000000  0.000000
2000-01-03  0.326266  0.746555  0.825070
2000-01-04  0.492115  0.508553  0.971966
2000-01-05  0.160850  0.403678  0.107497
2000-01-06  0.000000  0.000000  0.000000
2000-01-07  0.047433  0.103412  0.789594
2000-01-08  0.527788  0.415356  0.926681
2000-01-09  0.468794  0.458531  0.435696
2000-01-10  0.261224  0.599815  0.435548
Run Code Online (Sandbox Code Playgroud)