【问题标题】:TypeError: unsupported operand type(s) for -: 'str' and 'str' in python 3.x Anaconda类型错误:python 3.x Anaconda 中 -: 'str' 和 'str' 的不支持的操作数类型
【发布时间】:2017-10-13 17:39:25
【问题描述】:

我正在尝试在大型数据集中每小时计算一些实例。下面的代码似乎在 python 2.7 上运行良好,但我不得不将它升级到 3.x 最新版本的 python 以及 Anaconda 上的所有更新包。当我尝试执行程序时,我收到了str 错误

代码:

import pandas as pd
from datetime import datetime,time
import numpy as np

fn = r'00_input.csv'
cols = ['UserId', 'UserMAC', 'HotspotID', 'StartTime', 'StopTime']
df = pd.read_csv(fn, header=None, names=cols)

df['m'] = df.StopTime + df.StartTime
df['d'] = df.StopTime - df.StartTime

# 'start' and 'end' for the reporting DF: `r`
# which will contain equal intervals (1 hour in this case)
start = pd.to_datetime(df.StartTime.min(), unit='s').date()
end = pd.to_datetime(df.StopTime.max(), unit='s').date() + pd.Timedelta(days=1)

# building reporting DF: `r`
freq = '1H'  # 1 Hour frequency
idx = pd.date_range(start, end, freq=freq)
r = pd.DataFrame(index=idx)
r['start'] = (r.index - pd.datetime(1970,1,1)).total_seconds().astype(np.int64)

# 1 hour in seconds, minus one second (so that we will not count it twice)
interval = 60*60 - 1

r['LogCount'] = 0
r['UniqueIDCount'] = 0

for i, row in r.iterrows():
        # intervals overlap test
        # https://en.wikipedia.org/wiki/Interval_tree#Overlap_test
        # i've slightly simplified the calculations of m and d
        # by getting rid of division by 2,
        # because it can be done eliminating common terms
    u = df[np.abs(df.m - 2*row.start - interval) < df.d + interval].UserID
    r.ix[i, ['LogCount', 'UniqueIDCount']] = [len(u), u.nunique()]

r['Date'] = pd.to_datetime(r.start, unit='s').dt.date
r['Day'] = pd.to_datetime(r.start, unit='s').dt.weekday_name.str[:3]
r['StartTime'] = pd.to_datetime(r.start, unit='s').dt.time
r['EndTime'] = pd.to_datetime(r.start + interval + 1, unit='s').dt.time

#r.to_csv('results.csv', index=False)
#print(r[r.LogCount > 0])
#print (r['StartTime'], r['EndTime'], r['Day'], r['LogCount'], r['UniqueIDCount'])

rout =  r[['Date', 'StartTime', 'EndTime', 'Day', 'LogCount', 'UniqueIDCount'] ]
#print rout
rout.to_csv('o_1_hour.csv', index=False, header=False

)

我在哪里进行更改以获得无错误的执行

错误:

File "C:\Program Files\Anaconda3\lib\site-packages\pandas\core\ops.py", line 686, in <lambda>
    lambda x: op(x, rvalues))

TypeError: unsupported operand type(s) for -: 'str' and 'str'

感谢帮助,提前致谢

【问题讨论】:

  • print (df['StartTime'].dtypes)print (df['StopTime'].dtypes)df = pd.read_csv(fn, header=None, names=cols, parse_dates=[3,4]) 之后返回什么?
  • @jezrael 它甚至没有考虑打印语句,在更改提到下面的答案并包括打印语句后,我收到此错误TypeError: Can't convert 'int' object to str implicitly
  • 好的,但是没有它我找不到错误 - 所以由于某种原因不可能得到这个dtypes?因为如果是对象,则需要to_datetime(df['StartTime'], errros='coerce'),如果是datetime64,那么问题就不同了。第一行错误也是必要的,因为显然显示错误代码行。
  • 但如果数据不保密,您可以通过 Dropbox、gdocs 或将其发送到我的个人资料中的电子邮件给我。因为没有数据真的很难找到问题:(
  • 数据不是保密的,但它太大了(GBs)我在这里上传了一个迷你版的Dropbox数据:dropbox.com/s/n2lzimxks26a3bw/canada_mini_unixtime.csv?dl=0

标签: python pandas anaconda


【解决方案1】:

我认为您需要更改 header=0 以将第一行选择为标题 - 然后将列名替换为列表 cols

如果还是有问题,需要to_numeric,因为StartTimeStopTime中的一些值是字符串,被解析为NaN,替换为0最后一个转换为int的列:

cols = ['UserId', 'UserMAC', 'HotspotID', 'StartTime', 'StopTime']
df = pd.read_csv('canada_mini_unixtime.csv', header=0, names=cols)
#print (df)

df['StartTime'] = pd.to_numeric(df['StartTime'], errors='coerce').fillna(0).astype(int)
df['StopTime'] =  pd.to_numeric(df['StopTime'], errors='coerce').fillna(0).astype(int)

没有变化:

df['m'] = df.StopTime + df.StartTime
df['d'] = df.StopTime - df.StartTime
start = pd.to_datetime(df.StartTime.min(), unit='s').date()
end = pd.to_datetime(df.StopTime.max(), unit='s').date() + pd.Timedelta(days=1)

freq = '1H'  # 1 Hour frequency
idx = pd.date_range(start, end, freq=freq)
r = pd.DataFrame(index=idx)
r['start'] = (r.index - pd.datetime(1970,1,1)).total_seconds().astype(np.int64)

# 1 hour in seconds, minus one second (so that we will not count it twice)
interval = 60*60 - 1

r['LogCount'] = 0
r['UniqueIDCount'] = 0

ix 在最新版本的 pandas 中已弃用,因此请使用 loc 并且列名在 [] 中:

for i, row in r.iterrows():
        # intervals overlap test
        # https://en.wikipedia.org/wiki/Interval_tree#Overlap_test
        # i've slightly simplified the calculations of m and d
        # by getting rid of division by 2,
        # because it can be done eliminating common terms
    u = df.loc[np.abs(df.m - 2*row.start - interval) < df.d + interval, 'UserId']
    r.loc[i, ['LogCount', 'UniqueIDCount']] = [len(u), u.nunique()]

r['Date'] = pd.to_datetime(r.start, unit='s').dt.date
r['Day'] = pd.to_datetime(r.start, unit='s').dt.weekday_name.str[:3]
r['StartTime'] = pd.to_datetime(r.start, unit='s').dt.time
r['EndTime'] = pd.to_datetime(r.start + interval + 1, unit='s').dt.time

print (r)

【讨论】:

  • 当然..谢谢..我会进行更改并尝试执行程序并让您知道。再次感谢
  • 我有一堆代码要从 2.7 迁移到 3.x .. 我希望这对我有用 .. 从挂起的堆计数中减少一个也很重要.. 谢谢一堆..跨度>
  • 是的,我也是从 python 2 开始的,我知道它是什么。祝你好运!
  • 中的另一个地方给我错误 u = df[np.abs(df.StartTime - 2*row.start - interval)
  • 嗯,我错了。还有一个问题。我编辑答案。
【解决方案2】:

df['d'] = df.StopTime - df.StartTime 正在尝试从另一个字符串中减去一个字符串。我不知道您的数据是什么样的,但您可能希望将 StopTimeStartTime 解析为日期。试试

df = pd.read_csv(fn, header=None, names=cols, parse_dates=[3,4])

而不是df = pd.read_csv(fn, header=None, names=cols)

【讨论】:

  • 感谢您的回答:当我更改语句时,我收到此错误TypeError: Can't convert 'int' object to str implicitly
猜你喜欢
  • 2017-05-27
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-24
相关资源
最近更新 更多