我正在学习如何使用 Python 3.8 ( PEP 544 )中引入的协议类。
因此,typing.Protocol类是 的子类,ABCMeta并且它们的处理方式就像抽象类一样,并且具有允许使用结构子类型的额外好处。我试图思考现在我会使用什么抽象基类,但我却一片空白。
与 ABC 相比,协议类有哪些缺点(如果有)?也许它们的性能会受到影响?是否有任何特定情况表明 ABC 仍然是最佳选择?
我一直在阅读 PEP484 和 526,但仍然无法找出对没有初始值的变量进行类型注释的更好方法。
假设您有一个类,并且__init__要在类中声明一个变量,但不提供初始值(稍后在代码中进行赋值)。通常我通常会做的是:
from typing import Optional, List
class SomeClass:
def __init__(self) -> None:
self.some_value: Optional[int] = None
self.other_var: Optional[List] = None
def _some_method(self) -> None:
self.some_value = 42
Run Code Online (Sandbox Code Playgroud)
这是可行的,但我觉得使用Optional会变得__init__过于忙碌并且难以阅读。相反,我能做的是:
from typing import List
class SomeClass:
def __init__(self) -> None:
self.some_value: int
self.other_var: List
def _some_method(self) -> None:
self.some_value = 42
Run Code Online (Sandbox Code Playgroud)
显然,这会使变量未初始化,但只要在引用之前正确分配它们,一切都会正常工作,并且如果我在__init__.
使用第二种方法时,未初始化变量是否会出现任何具体问题?
我正在尝试安装 geopandas,通常会通过 pip 来安装,但它似乎与依赖项作斗争,所以我尝试通过 conda 包管理器进行安装。
一切都很顺利,直到我收到此错误:
Conda error: Cannot link a source that does not exist C:\ProgramData\Anaconda3\Scripts\conda.exe
Run Code Online (Sandbox Code Playgroud)
我检查了一下,指定的文件夹中有 conda.exe。我也有它的PATH变量。
我还查看了有关此错误的其他问题并尝试了建议的解决方案:
conda clean --all --yes
conda update conda
conda update anaconda
Run Code Online (Sandbox Code Playgroud)
但我每次仍然会遇到同样的错误。有人知道解决这个问题的其他方法吗?
谢谢!
编辑:
我尝试使用这两个选项安装 geopandas:
conda install geopandas
conda install --channel conda-forge geopandas
Run Code Online (Sandbox Code Playgroud)
输出conda info:
(C:\ProgramData\Anaconda3) C:\VULCAN_HOME>conda info
Current conda install:
platform : win-64
conda version : 4.3.30
conda is private : False
conda-env version : 4.3.30
conda-build version : 3.0.27
python version : 3.6.3.final.0 …Run Code Online (Sandbox Code Playgroud) 昨天,我问了一个有关 CORS 错误的问题,当我尝试从 Angular 应用程序向 FastApi 后端发出 POST 请求时,遇到了该错误。经过一些评论后,我决定删除该问题以更好地重新检查一切。
所以事情有点奇怪。在我的 FastApi 后端中,我有以下功能:
@app.post("/hello")
def read_root(request: Request):
print(request)
client_host = request.client.host
return {"client_host": client_host}
@app.post("/pattern-data")
def pattern_input(payload: PatternReconData) -> Dict:
# Does stuff and falls over tragically
return result # this doesn't happen of course
Run Code Online (Sandbox Code Playgroud)
在我的前端我正在尝试这两个:
this.apiService.sendRequest('hello', 'howdy').subscribe(
(response) => {
console.log(response);
},
(error: any) => {
console.log(error);
},
() => {
console.log('done');
}
);
this.apiService.sendRequest('pattern-data', payload).subscribe(
(response: SuccessResponse) => {
console.log(response);
/* do stuff */
},
(error: any) => { …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 Pandas DataFrame 中的日期列转换为日期时间格式。如果我不指定日期格式,它可以正常工作,但在代码中,由于时间格式不同,我会遇到问题。
10/10/2019 6:00欧洲日期格式的原始日期如下所示。
我尝试像这样指定格式:
df['PeriodStartDate'] = pd.to_datetime(df['PeriodStartDate'],
format="%d/%m/%Y")
Run Code Online (Sandbox Code Playgroud)
这会导致错误:unconverted data remains 6:00
然后,我尝试更新格式指令,但format="%d/%m/%Y %-I/%H"出现了另一个错误:'-' is a bad directive in format '%d/%m/%Y %-I/%H'尽管我认为to_datetime使用相同的指令,并且strftime在后者中%-I是允许的。
沮丧中,我决定砍掉绳子的末端,因为我真的不需要几小时和几分钟:
df['PeriodStartDate'] = df['PeriodStartDate'].str[:10]
df['PeriodStartDate'] = pd.to_datetime(df['PeriodStartDate'],
format="%d/%m/%Y")
Run Code Online (Sandbox Code Playgroud)
但这再次导致错误:ValueError: unconverted data remains:这当然是因为某些日期有 9 位数字,例如3/10/2019 6:00
不太确定从这里去哪里。
我正在努力重新格式化数据框中的一些数据,并且需要计算新的 timedelta 列的值,这是通过用系列向上移动一行时的开始日期减去事件的开始日期来完成的:
data['DURATION_NEW'] = (data['START'] - data['START'].shift(-1))
Run Code Online (Sandbox Code Playgroud)
这工作正常并创建一个 timedelta 列,但其中的数据格式非常奇怪:
foo['DURATION_NEW']
Out[80]:
0 -1 days +23:53:30
1 -1 days +15:35:00
2 -1 days +23:50:00
3 -1 days +23:49:00
4 -1 days +23:53:30
1459 -1 days +23:47:00
1461 -1 days +23:51:00
1462 -1 days +22:08:01
1463 -1 days +23:39:30
1464 NaT
Name: DURATION_NEW, Length: 1406, dtype: timedelta64[ns]
Run Code Online (Sandbox Code Playgroud)
我需要以某种方式转换这些数据以在几秒钟内显示。首先,我尝试将其转换为日期时间,但由于某种原因出现错误dtype timedelta64[ns] cannot be converted to datetime64[ns]。
接下来,我尝试手动重新转换它,同时指定我希望它在几秒钟内完成:
foo['DURATION_NEW'] = pd.to_timedelta(foo['DURATION_NEW'], unit='sec')
Run Code Online (Sandbox Code Playgroud)
那也没用。一切都保持原样。
我怎样才能正确地做到这一点?
假设我有一个像这样的 Polars 数据框:
df = pl.DataFrame({
'a': [0.3, 0.7, 0.5, 0.1, 0.9]
})
Run Code Online (Sandbox Code Playgroud)
现在我需要添加一个新列,根据列中的值'a'大于还是小于某个阈值来分配 1 或 0。在 Pandas 中我可以这样做:
import numpy as np
THRESHOLD = 0.5
df['new'] = np.where(df.a > THRESHOLD, 0, 1)
Run Code Online (Sandbox Code Playgroud)
我也可以在 Polars 中做一些非常类似的事情:
df = df.with_columns(
pl.lit(np.where(df.select('a').to_numpy() > THRESHOLD, 0, 1).ravel())
.alias('new')
)
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我确信在这里使用 NumPy 不是最佳实践。
我也尝试过类似的东西:
df = df.with_columns(
pl.lit(df.filter(pl.col('a') > THRESHOLD).select([0, 1]))
.alias('new')
)
Run Code Online (Sandbox Code Playgroud)
但使用这种语法我不断遇到以下错误:
DuplicateError Traceback (most recent call last)
Cell In[47], line 5
1 THRESHOLD = 0.5
2 DELAY_TOLERANCE = 10 …Run Code Online (Sandbox Code Playgroud) 最近几天我在工作中处理了大量 4-5 Gb 的 csv 文件,因此我知道它们通过读/写取得了多少进展,我在 pandas 的方法之上编写了几个包装函数。这一切似乎都运行得很好,虽然有一点开销,但便利性胜过大多数问题。
同时,在读取 csv 时,为了让进度条显示正确的百分比,我需要提前知道行数,因为这决定了有多少块。我想出的最简单的解决方案是简单地加载 csv 的第 0 列,然后开始加载其余部分并获取其大小。但是,当您拥有数百万行大小的文件时,这确实需要一些时间。
此外,读取单列所花费的总时间比例过高:读取 125 列、几百万行的 csv 中的单列大约需要 24 秒,读取整个文件则需要 63 秒。
这是我一直用来读取 csv 的函数:
def read_csv_with_progressbar(filename: str,
chunksize: int = 50000) -> pd.DataFrame:
length = pd.read_csv(filename, usecols=[0])
length = length.values.shape[0]
total = length//chunksize
chunk_list = []
chunks = pd.read_csv(filename, chunksize=chunksize)
with tqdm(total=total, file=sys.stdout) as pbar:
for chunk in chunks:
chunk_list.append(chunk)
pbar.set_description('Reading source csv file')
pbar.update(1)
df = pd.concat([i for i in chunk_list], axis=0)
return df
Run Code Online (Sandbox Code Playgroud)
有什么方法可以比使用我有缺陷的方法更快地获取 csv …
我喜欢dateutil.parser并经常使用它,因此我不必担心日期时间格式不一致,并且在大多数情况下它对我来说非常可靠。
但今天我花了一个小时调试试图理解为什么我在数据库中填充的日期都是 2022 年。日期格式是:2009:05:03 08:12:37存储在照片元数据中并使用exifpackage.json 提取。
感觉它应该是一种相当简单的解析格式,但这就是我分别使用dateutil和datetime模块得到的:
from dateutil.parser import parse
import datetime as dt
date_string = '2009:05:03 08:12:37'
wrong = parse(date_string, fuzzy=True)
correct = dt.datetime.strptime(date_string, "%Y:%m:%d %H:%M:%S")
print(wrong)
print(correct)
Out:
2022-07-25 08:12:37
2009-05-03 08:12:37
Run Code Online (Sandbox Code Playgroud)
正常解析和模糊解析都给出相同的结果。很奇怪,我什至不明白它是如何得出这个精确结果的。
看起来它尝试解析并成功完成时间,但无法解析日期并默认设置当前日期。这感觉像是一种非常危险的行为。它应该引发异常。