用PyPlot绘制平滑线

问题:用PyPlot绘制平滑线

我有以下绘制图形的简单脚本:

import matplotlib.pyplot as plt
import numpy as np

T = np.array([6, 7, 8, 9, 10, 11, 12])
power = np.array([1.53E+03, 5.92E+02, 2.04E+02, 7.24E+01, 2.72E+01, 1.10E+01, 4.70E+00])

plt.plot(T,power)
plt.show()

就目前而言,这条线从一条直线到另一条直线看起来不错,但在我看来可能会更好。我想要的是使两点之间的线平滑。在Gnuplot中,我会用绘制smooth cplines

在PyPlot中有一种简单的方法吗?我已经找到了一些教程,但是它们似乎都相当复杂。

I’ve got the following simple script that plots a graph:

import matplotlib.pyplot as plt
import numpy as np

T = np.array([6, 7, 8, 9, 10, 11, 12])
power = np.array([1.53E+03, 5.92E+02, 2.04E+02, 7.24E+01, 2.72E+01, 1.10E+01, 4.70E+00])

plt.plot(T,power)
plt.show()

As it is now, the line goes straight from point to point which looks ok, but could be better in my opinion. What I want is to smooth the line between the points. In Gnuplot I would have plotted with smooth cplines.

Is there an easy way to do this in PyPlot? I’ve found some tutorials, but they all seem rather complex.


回答 0

您可以用来scipy.interpolate.spline自己整理数据:

from scipy.interpolate import spline

# 300 represents number of points to make between T.min and T.max
xnew = np.linspace(T.min(), T.max(), 300)  

power_smooth = spline(T, power, xnew)

plt.plot(xnew,power_smooth)
plt.show()

scipy 0.19.0中已弃用样条线,请改用BSpline类。

从切换splineBSpline复制并不是简单的复制/粘贴操作,需要进行一些调整:

from scipy.interpolate import make_interp_spline, BSpline

# 300 represents number of points to make between T.min and T.max
xnew = np.linspace(T.min(), T.max(), 300) 

spl = make_interp_spline(T, power, k=3)  # type: BSpline
power_smooth = spl(xnew)

plt.plot(xnew, power_smooth)
plt.show()

之前:

后:

You could use scipy.interpolate.spline to smooth out your data yourself:

from scipy.interpolate import spline

# 300 represents number of points to make between T.min and T.max
xnew = np.linspace(T.min(), T.max(), 300)  

power_smooth = spline(T, power, xnew)

plt.plot(xnew,power_smooth)
plt.show()

spline is deprecated in scipy 0.19.0, use BSpline class instead.

Switching from spline to BSpline isn’t a straightforward copy/paste and requires a little tweaking:

from scipy.interpolate import make_interp_spline, BSpline

# 300 represents number of points to make between T.min and T.max
xnew = np.linspace(T.min(), T.max(), 300) 

spl = make_interp_spline(T, power, k=3)  # type: BSpline
power_smooth = spl(xnew)

plt.plot(xnew, power_smooth)
plt.show()

Before:

After:


回答 1

对于此示例,样条曲线效果很好,但是如果函数固有地不平滑,并且您想要平滑的版本,则还可以尝试:

from scipy.ndimage.filters import gaussian_filter1d

ysmoothed = gaussian_filter1d(y, sigma=2)
plt.plot(x, ysmoothed)
plt.show()

如果增加sigma,可以获得更平滑的功能。

请谨慎处理这一内容。它会修改原始值,可能不是您想要的。

For this example spline works well, but if the function is not smooth inherently and you want to have smoothed version you can also try:

from scipy.ndimage.filters import gaussian_filter1d

ysmoothed = gaussian_filter1d(y, sigma=2)
plt.plot(x, ysmoothed)
plt.show()

if you increase sigma you can get a more smoothed function.

Proceed with caution with this one. It modifies the original values and may not be what you want.


回答 2

我认为您的意思是曲线拟合,而不是从您的问题的上下文来看抗锯齿。PyPlot没有任何内置的这种支持,但你可以很容易地实现一些基本的曲线拟合自己,喜欢看到的代码在这里,或者如果你使用GuiQwt它有一个曲线拟合模块。(您可能也可以从SciPy窃取代码来执行此操作)。

I presume you mean curve-fitting and not anti-aliasing from the context of your question. PyPlot doesn’t have any built-in support for this, but you can easily implement some basic curve-fitting yourself, like the code seen here, or if you’re using GuiQwt it has a curve fitting module. (You could probably also steal the code from SciPy to do this as well).


回答 3

有关scipy.interpolate一些示例,请参见文档。

以下示例演示了其在线性和三次样条插值中的用法:

>>> from scipy.interpolate import interp1d

>>> x = np.linspace(0, 10, num=11, endpoint=True)
>>> y = np.cos(-x**2/9.0)
>>> f = interp1d(x, y)
>>> f2 = interp1d(x, y, kind='cubic')

>>> xnew = np.linspace(0, 10, num=41, endpoint=True)
>>> import matplotlib.pyplot as plt
>>> plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
>>> plt.legend(['data', 'linear', 'cubic'], loc='best')
>>> plt.show()

See the scipy.interpolate documentation for some examples.

The following example demonstrates its use, for linear and cubic spline interpolation:

>>> from scipy.interpolate import interp1d

>>> x = np.linspace(0, 10, num=11, endpoint=True)
>>> y = np.cos(-x**2/9.0)
>>> f = interp1d(x, y)
>>> f2 = interp1d(x, y, kind='cubic')

>>> xnew = np.linspace(0, 10, num=41, endpoint=True)
>>> import matplotlib.pyplot as plt
>>> plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
>>> plt.legend(['data', 'linear', 'cubic'], loc='best')
>>> plt.show()


在matplotlib中将x轴移动到绘图的顶部

问题:在matplotlib中将x轴移动到绘图的顶部

基于关于matplotlib中的热图的问题,我想将x轴标题移动到图的顶部。

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.set_label_position('top') # <-- This doesn't work!

ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()

但是,调用matplotlib的set_label_position(如上所述)似乎没有达到预期的效果。这是我的输出:

我究竟做错了什么?

Based on this question about heatmaps in matplotlib, I wanted to move the x-axis titles to the top of the plot.

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.set_label_position('top') # <-- This doesn't work!

ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()

However, calling matplotlib’s set_label_position (as notated above) doesn’t seem to have the desired effect. Here’s my output:

What am I doing wrong?


回答 0

ax.xaxis.tick_top()

将刻度线放在图像的顶部。命令

ax.set_xlabel('X LABEL')    
ax.xaxis.set_label_position('top') 

影响标签,而不影响刻度线。

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()

ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()

Use

ax.xaxis.tick_top()

to place the tick marks at the top of the image. The command

ax.set_xlabel('X LABEL')    
ax.xaxis.set_label_position('top') 

affects the label, not the tick marks.

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()

ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()


回答 1

您想要set_ticks_position而不是set_label_position

ax.xaxis.set_ticks_position('top') # the rest is the same

这给了我:

You want set_ticks_position rather than set_label_position:

ax.xaxis.set_ticks_position('top') # the rest is the same

This gives me:


回答 2

tick_params对于设置刻度属性非常有用。可以使用以下命令将标签移到顶部:

    ax.tick_params(labelbottom=False,labeltop=True)

tick_params is very useful for setting tick properties. Labels can be moved to the top with:

    ax.tick_params(labelbottom=False,labeltop=True)

回答 3

如果要让刻度(而不是标签)显示在顶部和底部(而不仅仅是顶部),则必须做一些额外的按摩。我可以做到的唯一方法是对unutbu的代码进行较小的更改:

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.xaxis.set_ticks_position('both') # THIS IS THE ONLY CHANGE

ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()

输出:

You’ve got to do some extra massaging if you want the ticks (not labels) to show up on the top and bottom (not just the top). The only way I could do this is with a minor change to unutbu’s code:

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.xaxis.set_ticks_position('both') # THIS IS THE ONLY CHANGE

ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()

Output:


指定输入参数argparse python的格式

问题:指定输入参数argparse python的格式

我有一个需要一些命令行输入的python脚本,并且我正在使用argparse进行解析。我发现文档有点混乱,找不到在输入参数中检查格式的方法。这个示例脚本解释了我检查格式的意思:

parser.add_argument('-s', "--startdate", help="The Start Date - format YYYY-MM-DD ", required=True)
parser.add_argument('-e', "--enddate", help="The End Date format YYYY-MM-DD (Inclusive)", required=True)
parser.add_argument('-a', "--accountid", type=int, help='Account ID for the account for which data is required (Default: 570)')
parser.add_argument('-o', "--outputpath", help='Directory where output needs to be stored (Default: ' + os.path.dirname(os.path.abspath(__file__)))

我需要检查选项,-s并且-e用户输入的格式为YYYY-MM-DD。我不知道argparse中有一个选项可以完成此任务。

I have a python script that requires some command line inputs and I am using argparse for parsing them. I found the documentation a bit confusing and couldn’t find a way to check for a format in the input parameters. What I mean by checking format is explained with this example script:

parser.add_argument('-s', "--startdate", help="The Start Date - format YYYY-MM-DD ", required=True)
parser.add_argument('-e', "--enddate", help="The End Date format YYYY-MM-DD (Inclusive)", required=True)
parser.add_argument('-a', "--accountid", type=int, help='Account ID for the account for which data is required (Default: 570)')
parser.add_argument('-o', "--outputpath", help='Directory where output needs to be stored (Default: ' + os.path.dirname(os.path.abspath(__file__)))

I need to check for option -s and -e that the input by the user is in the format YYYY-MM-DD. Is there an option in argparse that I do not know of which accomplishes this.


回答 0

根据文档

type关键字参数add_argument()允许执行任何必要的类型检查和类型转换… type=可以接受带有单个字符串参数并返回转换后值的任何可调用对象

您可以执行以下操作:

def valid_date(s):
    try:
        return datetime.strptime(s, "%Y-%m-%d")
    except ValueError:
        msg = "Not a valid date: '{0}'.".format(s)
        raise argparse.ArgumentTypeError(msg)

然后将其用作type

parser.add_argument("-s", 
                    "--startdate", 
                    help="The Start Date - format YYYY-MM-DD", 
                    required=True, 
                    type=valid_date)

Per the documentation:

The type keyword argument of add_argument() allows any necessary type-checking and type conversions to be performed … type= can take any callable that takes a single string argument and returns the converted value

You could do something like:

def valid_date(s):
    try:
        return datetime.strptime(s, "%Y-%m-%d")
    except ValueError:
        msg = "Not a valid date: '{0}'.".format(s)
        raise argparse.ArgumentTypeError(msg)

Then use that as type:

parser.add_argument("-s", 
                    "--startdate", 
                    help="The Start Date - format YYYY-MM-DD", 
                    required=True, 
                    type=valid_date)

回答 1

只是为了补充上面的答案,如果您想将lambda函数保持为单一格式,则可以使用该函数。例如:

parser.add_argument('--date', type=lambda d: datetime.strptime(d, '%Y%m%d'))

旧线程,但问题至少仍然与我有关!

Just to add on to the answer above, you can use a lambda function if you want to keep it to a one-liner. For example:

parser.add_argument('--date', type=lambda d: datetime.strptime(d, '%Y%m%d'))

Old thread but the question was still relevant for me at least!


回答 2

对于其他通过搜索引擎实现此目标的人:在Python 3.7中,您可以使用标准的.fromisoformatclass方法,而不是为ISO-8601兼容日期重新发明轮子,例如:

parser.add_argument('-s', "--startdate",
    help="The Start Date - format YYYY-MM-DD",
    required=True,
    type=datetime.date.fromisoformat)
parser.add_argument('-e', "--enddate",
    help="The End Date format YYYY-MM-DD (Inclusive)",
    required=True,
    type=datetime.date.fromisoformat)

For others who hit this via search engines: in Python 3.7, you can use the standard .fromisoformat class method instead of reinventing the wheel for ISO-8601 compliant dates, e.g.:

parser.add_argument('-s', "--startdate",
    help="The Start Date - format YYYY-MM-DD",
    required=True,
    type=datetime.date.fromisoformat)
parser.add_argument('-e', "--enddate",
    help="The End Date format YYYY-MM-DD (Inclusive)",
    required=True,
    type=datetime.date.fromisoformat)

如何禁用Django的CSRF验证?

问题:如何禁用Django的CSRF验证?

我已经在中注释掉了csrf处理器和中间件产品线settings.py

122 
123 TEMPLATE_CONTEXT_PROCESSORS = (
124     'django.contrib.auth.context_processors.auth',
125 #    'django.core.context_processors.csrf',
126     'django.core.context_processors.request',
127     'django.core.context_processors.static',
128     'cyathea.processors.static',
129 )
130 
131 MIDDLEWARE_CLASSES = (
132     'django.middleware.common.CommonMiddleware',
133     'django.contrib.sessions.middleware.SessionMiddleware',
134 #    'django.middleware.csrf.CsrfViewMiddleware',
135     'django.contrib.auth.middleware.AuthenticationMiddleware',
136     'django.contrib.messages.middleware.MessageMiddleware',
137     'django.middleware.locale.LocaleMiddleware',
138     # Uncomment the next line for simple clickjacking protection:
139     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )

但是,当我使用Ajax发送请求时,Django仍然会响应“ csrf令牌不正确或丢失”,并且在将X-CSRFToken添加到标头后,请求将会成功。

这里发生了什么 ?

I have commented out csrf processor and middleware lines in settings.py:

122 
123 TEMPLATE_CONTEXT_PROCESSORS = (
124     'django.contrib.auth.context_processors.auth',
125 #    'django.core.context_processors.csrf',
126     'django.core.context_processors.request',
127     'django.core.context_processors.static',
128     'cyathea.processors.static',
129 )
130 
131 MIDDLEWARE_CLASSES = (
132     'django.middleware.common.CommonMiddleware',
133     'django.contrib.sessions.middleware.SessionMiddleware',
134 #    'django.middleware.csrf.CsrfViewMiddleware',
135     'django.contrib.auth.middleware.AuthenticationMiddleware',
136     'django.contrib.messages.middleware.MessageMiddleware',
137     'django.middleware.locale.LocaleMiddleware',
138     # Uncomment the next line for simple clickjacking protection:
139     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )

But when I use Ajax to send a request, Django still respond ‘csrf token is incorrect or missing’, and after adding X-CSRFToken to headers, the request would succeed.

What is going on here ?


回答 0

如果只需要一些视图而不使用CSRF,则可以使用@csrf_exempt

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

您可以在Django文档中找到更多示例和其他场景:

If you just need some views not to use CSRF, you can use @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

You can find more examples and other scenarios in the Django documentation:


回答 1

要为基于类的视图禁用CSRF,以下对我有用。
使用Django 1.10和python 3.5.2

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello world')

To disable CSRF for class based views the following worked for me.
Using django 1.10 and python 3.5.2

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello world')

回答 2

setting.pyMIDDLEWARE中,您可以简单地删除/注释此行:

'django.middleware.csrf.CsrfViewMiddleware',

In setting.py in MIDDLEWARE you can simply remove/comment this line:

'django.middleware.csrf.CsrfViewMiddleware',

回答 3

对于Django 2

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

必须settings.MIDDLEWARE在适当的时候(例如在您的测试设置中)添加该中间件。

注意:不再调用该设置MIDDLEWARE_CLASSES

For Django 2:

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

That middleware must be added to settings.MIDDLEWARE when appropriate (in your test settings for example).

Note: the setting isn’t not called MIDDLEWARE_CLASSES anymore.


回答 4

答案可能不合适,但希望对您有帮助

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

使用这样的中间件有助于调试请求并检查生产服务器中的csrf。

The answer might be inappropriate, but I hope it helps you

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

Having middleware like this helps to debug requests and to check csrf in production servers.


回答 5

这里的问题是SessionAuthentication执行自己的CSRF验证。这就是为什么即使在注释CSRF中间件的情况下也出现CSRF丢失错误的原因。您可以在每个视图中添加@csrf_exempt,但是如果您想禁用CSRF并为整个应用进行会话身份验证,则可以添加一个额外的中间件,如下所示:

class DisableCSRFMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    setattr(request, '_dont_enforce_csrf_checks', True)
    response = self.get_response(request)
    return response

我在myapp / middle.py中创建了该类,然后在Middleware的settings.py中导入了该中间件

MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'myapp.middle.DisableCSRFMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

可以在Django 1.11上使用DRF

The problem here is that SessionAuthentication performs its own CSRF validation. That is why you get the CSRF missing error even when the CSRF Middleware is commented. You could add @csrf_exempt to every view, but if you want to disable CSRF and have session authentication for the whole app, you can add an extra middleware like this –

class DisableCSRFMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    setattr(request, '_dont_enforce_csrf_checks', True)
    response = self.get_response(request)
    return response

I created this class in myapp/middle.py Then import this middleware in Middleware in settings.py

MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'myapp.middle.DisableCSRFMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

That works with DRF on django 1.11


回答 6

如果要在“全局”中禁用它,则可以编写自定义中间件,如下所示

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

然后将该类添加youappname.middlewarefilename.DisableCsrfCheckMIDDLEWARE_CLASSES列表中,然后django.middleware.csrf.CsrfViewMiddleware

If you want disable it in Global, you can write a custom middleware, like this

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

then add this class youappname.middlewarefilename.DisableCsrfCheck to MIDDLEWARE_CLASSES lists, before django.middleware.csrf.CsrfViewMiddleware


回答 7

CSRF可以在视图级别强制执行,不能全局禁用

在某些情况下,这很痛苦,但是,“这是为了安全”。保留这些AAA等级。

https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps

CSRF can be enforced at the view level, which can’t be disabled globally.

In some cases this is a pain, but um, “it’s for security”. Gotta retain those AAA ratings.

https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps


回答 8

@WoooHaaaa一些第三方程序包使用’django.middleware.csrf.CsrfViewMiddleware’中间件。例如,我使用django-rest-oauth,即使禁用了这些东西,我也遇到了类似您的问题。也许这些软件包像我的案例一样响应了您的请求,因为您使用了身份验证修饰符之类的东西。

@WoooHaaaa some third party packages use ‘django.middleware.csrf.CsrfViewMiddleware’ middleware. for example i use django-rest-oauth and i have problem like you even after disabling those things. maybe these packages responded to your request like my case, because you use authentication decorator and something like this.


在python shell中导入pyspark

问题:在python shell中导入pyspark

这是其他论坛上从未有人回答过的其他人的问题的副本,因此我想在这里重新提问,因为我有同样的问题。(请参阅http://geekple.com/blogs/feeds/Xgzu7/posts/351703064084736

我已经在机器上正确安装了Spark,并且在使用./bin/pyspark作为我的python解释器时,能够使用pyspark模块运行python程序而不会出错。

但是,当我尝试运行常规Python Shell时,当我尝试导入pyspark模块时,出现此错误:

from pyspark import SparkContext

它说

"No module named pyspark".

我怎样才能解决这个问题?我是否需要设置环境变量以将Python指向pyspark标头/库/等?如果我的spark安装是/ spark /,我需要包括哪些pyspark路径?还是只能从pyspark解释器运行pyspark程序?

This is a copy of someone else’s question on another forum that was never answered, so I thought I’d re-ask it here, as I have the same issue. (See http://geekple.com/blogs/feeds/Xgzu7/posts/351703064084736)

I have Spark installed properly on my machine and am able to run python programs with the pyspark modules without error when using ./bin/pyspark as my python interpreter.

However, when I attempt to run the regular Python shell, when I try to import pyspark modules I get this error:

from pyspark import SparkContext

and it says

"No module named pyspark".

How can I fix this? Is there an environment variable I need to set to point Python to the pyspark headers/libraries/etc.? If my spark installation is /spark/, which pyspark paths do I need to include? Or can pyspark programs only be run from the pyspark interpreter?


回答 0

这是一个简单的方法(如果您不关心它的工作原理!!!)

使用findspark

  1. 转到您的python shell

    pip install findspark
    
    import findspark
    findspark.init()
  2. 导入必要的模块

    from pyspark import SparkContext
    from pyspark import SparkConf
  3. 完成!!!

Here is a simple method (If you don’t bother about how it works!!!)

Use findspark

  1. Go to your python shell

    pip install findspark
    
    import findspark
    findspark.init()
    
  2. import the necessary modules

    from pyspark import SparkContext
    from pyspark import SparkConf
    
  3. Done!!!


回答 1

如果打印出这样的错误:

ImportError:没有名为py4j.java_gateway的模块

请将$ SPARK_HOME / python / build添加到PYTHONPATH:

export SPARK_HOME=/Users/pzhang/apps/spark-1.1.0-bin-hadoop2.4
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/build:$PYTHONPATH

If it prints such error:

ImportError: No module named py4j.java_gateway

Please add $SPARK_HOME/python/build to PYTHONPATH:

export SPARK_HOME=/Users/pzhang/apps/spark-1.1.0-bin-hadoop2.4
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/build:$PYTHONPATH

回答 2

原来pyspark bin是LOADING python,并且会自动加载正确的库路径。签出$ SPARK_HOME / bin / pyspark:

# Add the PySpark classes to the Python path:
export PYTHONPATH=$SPARK_HOME/python/:$PYTHONPATH

我将此行添加到我的.bashrc文件中,现在可以正确找到模块了!

Turns out that the pyspark bin is LOADING python and automatically loading the correct library paths. Check out $SPARK_HOME/bin/pyspark :

# Add the PySpark classes to the Python path:
export PYTHONPATH=$SPARK_HOME/python/:$PYTHONPATH

I added this line to my .bashrc file and the modules are now correctly found!


回答 3

不要将py文件运行为:python filename.py 而是使用:spark-submit filename.py

dont run your py file as: python filename.py instead use: spark-submit filename.py


回答 4

通过导出SPARK路径和Py4j路径,它开始起作用:

export SPARK_HOME=/usr/local/Cellar/apache-spark/1.5.1
export PYTHONPATH=$SPARK_HOME/libexec/python:$SPARK_HOME/libexec/python/build:$PYTHONPATH
PYTHONPATH=$SPARK_HOME/python/lib/py4j-0.8.2.1-src.zip:$PYTHONPATH 
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/build:$PYTHONPATH

因此,如果您不想在每次启动Python Shell时都键入这些内容,则可能需要将其添加到.bashrc文件中

By exporting the SPARK path and the Py4j path, it started to work:

export SPARK_HOME=/usr/local/Cellar/apache-spark/1.5.1
export PYTHONPATH=$SPARK_HOME/libexec/python:$SPARK_HOME/libexec/python/build:$PYTHONPATH
PYTHONPATH=$SPARK_HOME/python/lib/py4j-0.8.2.1-src.zip:$PYTHONPATH 
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/build:$PYTHONPATH

So, if you don’t want to type these everytime you want to fire up the Python shell, you might want to add it to your .bashrc file


回答 5

在Mac上,我使用Homebrew来安装Spark(公式为“ apache-spark”)。然后,我以这种方式设置PYTHONPATH,以便Python导入起作用:

export SPARK_HOME=/usr/local/Cellar/apache-spark/1.2.0
export PYTHONPATH=$SPARK_HOME/libexec/python:$SPARK_HOME/libexec/python/build:$PYTHONPATH

用Mac上的实际apache-spark版本替换“ 1.2.0”。

On Mac, I use Homebrew to install Spark (formula “apache-spark”). Then, I set the PYTHONPATH this way so the Python import works:

export SPARK_HOME=/usr/local/Cellar/apache-spark/1.2.0
export PYTHONPATH=$SPARK_HOME/libexec/python:$SPARK_HOME/libexec/python/build:$PYTHONPATH

Replace the “1.2.0” with the actual apache-spark version on your mac.


回答 6

为了在pyspark中执行Spark,需要两个组件一起工作:

  • pyspark python包
  • JVM中的Spark实例

在使用spark-submit或pyspark启动事物时,这些脚本将同时处理这两个脚本,即它们设置了PYTHONPATH,PATH等,以便您的脚本可以找到pyspark,并且它们还启动spark实例,并根据您的参数进行配置,例如–master X

另外,也可以绕过这些脚本,并直接在python解释器中运行spark应用程序python myscript.py。当spark脚本开始变得更加复杂并最终收到自己的args时,这尤其有趣。

  1. 确保pyspark软件包可以被Python解释器找到。如前所述,可以将spark / python目录添加到PYTHONPATH或使用pip install直接安装pyspark。
  2. 从您的脚本(曾经传递给pyspark的脚本)中设置spark实例的参数。
    • 对于通常使用–conf设置的spark配置,它们在SparkSession.builder.config中使用配置对象(或字符串配置)进行定义
    • 对于当前的主要选项(例如–master或–driver-mem),您可以通过写入PYSPARK_SUBMIT_ARGS环境变量来进行设置。为了使事情更干净,更安全,您可以在Python本身中进行设置,并且启动时spark会读取它。
  3. 启动实例,只需要您getOrCreate()从构建器对象调用即可。

因此,您的脚本可以具有以下内容:

from pyspark.sql import SparkSession

if __name__ == "__main__":
    if spark_main_opts:
        # Set main options, e.g. "--master local[4]"
        os.environ['PYSPARK_SUBMIT_ARGS'] = spark_main_opts + " pyspark-shell"

    # Set spark config
    spark = (SparkSession.builder
             .config("spark.checkpoint.compress", True)
             .config("spark.jars.packages", "graphframes:graphframes:0.5.0-spark2.1-s_2.11")
             .getOrCreate())

For a Spark execution in pyspark two components are required to work together:

  • pyspark python package
  • Spark instance in a JVM

When launching things with spark-submit or pyspark, these scripts will take care of both, i.e. they set up your PYTHONPATH, PATH, etc, so that your script can find pyspark, and they also start the spark instance, configuring according to your params, e.g. –master X

Alternatively, it is possible to bypass these scripts and run your spark application directly in the python interpreter likepython myscript.py. This is especially interesting when spark scripts start to become more complex and eventually receive their own args.

  1. Ensure the pyspark package can be found by the Python interpreter. As already discussed either add the spark/python dir to PYTHONPATH or directly install pyspark using pip install.
  2. Set the parameters of spark instance from your script (those that used to be passed to pyspark).
    • For spark configurations as you’d normally set with –conf they are defined with a config object (or string configs) in SparkSession.builder.config
    • For main options (like –master, or –driver-mem) for the moment you can set them by writing to the PYSPARK_SUBMIT_ARGS environment variable. To make things cleaner and safer you can set it from within Python itself, and spark will read it when starting.
  3. Start the instance, which just requires you to call getOrCreate() from the builder object.

Your script can therefore have something like this:

from pyspark.sql import SparkSession

if __name__ == "__main__":
    if spark_main_opts:
        # Set main options, e.g. "--master local[4]"
        os.environ['PYSPARK_SUBMIT_ARGS'] = spark_main_opts + " pyspark-shell"

    # Set spark config
    spark = (SparkSession.builder
             .config("spark.checkpoint.compress", True)
             .config("spark.jars.packages", "graphframes:graphframes:0.5.0-spark2.1-s_2.11")
             .getOrCreate())

回答 7

要摆脱ImportError: No module named py4j.java_gateway,您需要添加以下几行:

import os
import sys


os.environ['SPARK_HOME'] = "D:\python\spark-1.4.1-bin-hadoop2.4"


sys.path.append("D:\python\spark-1.4.1-bin-hadoop2.4\python")
sys.path.append("D:\python\spark-1.4.1-bin-hadoop2.4\python\lib\py4j-0.8.2.1-src.zip")

try:
    from pyspark import SparkContext
    from pyspark import SparkConf

    print ("success")

except ImportError as e:
    print ("error importing spark modules", e)
    sys.exit(1)

To get rid of ImportError: No module named py4j.java_gateway, you need to add following lines:

import os
import sys


os.environ['SPARK_HOME'] = "D:\python\spark-1.4.1-bin-hadoop2.4"


sys.path.append("D:\python\spark-1.4.1-bin-hadoop2.4\python")
sys.path.append("D:\python\spark-1.4.1-bin-hadoop2.4\python\lib\py4j-0.8.2.1-src.zip")

try:
    from pyspark import SparkContext
    from pyspark import SparkConf

    print ("success")

except ImportError as e:
    print ("error importing spark modules", e)
    sys.exit(1)

回答 8

在Windows 10上,以下内容对我有用。我使用“设置” >“ 编辑您的帐户的环境变量添加了以下环境变量:

SPARK_HOME=C:\Programming\spark-2.0.1-bin-hadoop2.7
PYTHONPATH=%SPARK_HOME%\python;%PYTHONPATH%

(将“ C:\ Programming \ …”更改为安装了spark的文件夹)

On Windows 10 the following worked for me. I added the following environment variables using Settings > Edit environment variables for your account:

SPARK_HOME=C:\Programming\spark-2.0.1-bin-hadoop2.7
PYTHONPATH=%SPARK_HOME%\python;%PYTHONPATH%

(change “C:\Programming\…” to the folder in which you have installed spark)


回答 9

对于Linux用户,以下是在PYTHONPATH中包含pyspark libaray的正确方法(并且不是硬编码)。PATH的两个部分都是必需的:

  1. pyspark Python模块本身的路径,以及
  2. 导入时pyspark模块依赖的压缩库的路径

请注意以下内容,压缩库的版本是动态确定的,因此我们不会对其进行硬编码。

export PYTHONPATH=${SPARK_HOME}/python/:$(echo ${SPARK_HOME}/python/lib/py4j-*-src.zip):${PYTHONPATH}

For Linux users, the following is the correct (and non-hard-coded) way of including the pyspark libaray in PYTHONPATH. Both PATH parts are necessary:

  1. The path to the pyspark Python module itself, and
  2. The path to the zipped library that that pyspark module relies on when imported

Notice below that the zipped library version is dynamically determined, so we do not hard-code it.

export PYTHONPATH=${SPARK_HOME}/python/:$(echo ${SPARK_HOME}/python/lib/py4j-*-src.zip):${PYTHONPATH}

回答 10

我正在CentOS VM上运行一个火花集群,该集群是从cloudera yum软件包安装的。

必须设置以下变量才能运行pyspark。

export SPARK_HOME=/usr/lib/spark;
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.9-src.zip:$PYTHONPATH

I am running a spark cluster, on CentOS VM, which is installed from cloudera yum packages.

Had to set the following variables to run pyspark.

export SPARK_HOME=/usr/lib/spark;
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.9-src.zip:$PYTHONPATH

回答 11

export PYSPARK_PYTHON=/home/user/anaconda3/bin/python
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook'

这就是我将Anaconda发行版与Spark结合使用的过程。这是独立于Spark版本的。您可以将第一行更改为用户的python bin。另外,从Spark 2.2.0起,PySpark作为PyPi上的独立程序包提供,但我尚未对其进行测试。

export PYSPARK_PYTHON=/home/user/anaconda3/bin/python
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook'

This is what I did for using my Anaconda distribution with Spark. This is Spark version independent. You can change the first line to your users’ python bin. Also, as of Spark 2.2.0 PySpark is available as a Stand-alone package on PyPi but I am yet to test it out.


回答 12

您可以使用以下方式获取pyspark pathpython中的in pip(如果您已使用PIP安装了pyspark),如下所示

pip show pyspark

You can get the pyspark path in python using pip (if you have installed pyspark using PIP) as below

pip show pyspark

回答 13

我有同样的问题。

还要确保您使用的是正确的python版本,并且要以正确的pip版本进行安装。就我而言:我同时拥有python 2.7和3.x。我已经安装了pyspark与

pip2.7安装pyspark

而且有效。

I had the same problem.

Also make sure you are using right python version and you are installing it with right pip version. in my case: I had both python 2.7 and 3.x. I have installed pyspark with

pip2.7 install pyspark

and it worked.


回答 14

我收到此错误,是因为我尝试提交的python脚本称为pyspark.py(facepalm)。解决方法是按照上述建议设置我的PYTHONPATH,然后将脚本重命名为pyspark_test.py并清理基于我的脚本原始名称创建的pyspark.pyc并清除此错误。

I got this error because the python script I was trying to submit was called pyspark.py (facepalm). The fix was to set my PYTHONPATH as recommended above, then rename the script to pyspark_test.py and clean up the pyspark.pyc that was created based on my scripts original name and that cleared this error up.


回答 15

对于DSE(DataStax Cassandra和Spark),需要在PYTHONPATH中添加以下位置

export PYTHONPATH=/usr/share/dse/resources/spark/python:$PYTHONPATH

然后使用dse pyspark获取路径中的模块。

dse pyspark

In the case of DSE (DataStax Cassandra & Spark) The following location needs to be added to PYTHONPATH

export PYTHONPATH=/usr/share/dse/resources/spark/python:$PYTHONPATH

Then use the dse pyspark to get the modules in path.

dse pyspark

回答 16

我遇到了同样的问题,将在上面提出的解决方案中添加一件事。在Mac OS X上使用Homebrew安装Spark时,您需要更正py4j路径地址,以在路径中包含libexec(记住将py4j版本更改为您拥有的版本);

PYTHONPATH=$SPARK_HOME/libexec/python/lib/py4j-0.9-src.zip:$PYTHONPATH

I had this same problem and would add one thing to the proposed solutions above. When using Homebrew on Mac OS X to install Spark you will need to correct the py4j path address to include libexec in the path (remembering to change py4j version to the one you have);

PYTHONPATH=$SPARK_HOME/libexec/python/lib/py4j-0.9-src.zip:$PYTHONPATH

回答 17

就我而言,它是在另一个python dist_package(python 3.5)上安装的,而我正在使用python 3.6,因此以下内容有所帮助:

python -m pip install pyspark

In my case it was getting install at a different python dist_package (python 3.5) whereas I was using python 3.6, so the below helped:

python -m pip install pyspark

回答 18

您还可以创建一个以Alpine作为操作系统,并以Python和Pyspark作为软件包的Docker容器。这样就将所有内容打包了。

You can also create a Docker container with Alpine as the OS and the install Python and Pyspark as packages. That will have it all containerised.


从异常对象中提取回溯信息

问题:从异常对象中提取回溯信息

给定一个Exception对象(来源不明),有没有办法获取其回溯?我有这样的代码:

def stuff():
   try:
       .....
       return useful
   except Exception as e:
       return e

result = stuff()
if isinstance(result, Exception):
    result.traceback <-- How?

获得异常后,如何从Exception对象中提取回溯?

Given an Exception object (of unknown origin) is there way to obtain its traceback? I have code like this:

def stuff():
   try:
       .....
       return useful
   except Exception as e:
       return e

result = stuff()
if isinstance(result, Exception):
    result.traceback <-- How?

How can I extract the traceback from the Exception object once I have it?


回答 0

这个问题的答案取决于您使用的Python版本。

在Python 3中

很简单:异常附带了一个__traceback__包含回溯的属性。此属性也是可写的,并且可以使用with_traceback异常方法方便地设置:

raise Exception("foo occurred").with_traceback(tracebackobj)

这些功能在raise文档中作了最少描述。

这部分答案应归功于Vyctor,后者首先发布了此信息。我之所以将其包含在此处,仅是因为此答案停留在顶部,并且Python 3变得越来越普遍。

在Python 2中

这很烦人。回溯的麻烦在于它们具有对堆栈框架的引用,而堆栈框架具有对回溯的引用,这些回溯具有对引用了…的堆栈框架的引用。这给垃圾收集器带来了问题。(感谢ecatmur首先指出这一点。)

解决此问题的一种好方法是在离开该子句后以手术方式中断循环except,这就是Python 3所做的。Python 2解决方案更加丑陋:为您提供了一个即席函数sys.exc_info(),该函数仅在 except 子句中有效。它返回一个包含异常,异常类型和当前正在处理的异常的回溯的元组。

因此,如果您在except子句中,则可以将的输出sys.exc_info()traceback模块一起使用来做各种有用的事情:

>>> import sys, traceback
>>> def raise_exception():
...     try:
...         raise Exception
...     except Exception:
...         ex_type, ex, tb = sys.exc_info()
...         traceback.print_tb(tb)
...     finally:
...         del tb
... 
>>> raise_exception()
  File "<stdin>", line 3, in raise_exception

但是,随着您的编辑表示,你正在试图获得该回溯,如果你的异常没有被处理的已打印,它之后已经被处理。这个问题要难得多。不幸的是,在不处理任何异常时sys.exc_info返回(None, None, None)。其他相关sys属性也无济于事。sys.exc_traceback不处理任何异常时不推荐使用且未定义;sys.last_traceback似乎很完美,但似乎仅在交互式会话中定义。

如果可以控制如何引发异常,则可以使用inspect自定义异常来存储某些信息。但是我不完全确定那将如何工作。

实话实说,捕获并返回异常是一件不寻常的事情。这可能表明您仍然需要进行重构。

The answer to this question depends on the version of Python you’re using.

In Python 3

It’s simple: exceptions come equipped with a __traceback__ attribute that contains the traceback. This attribute is also writable, and can be conveniently set using the with_traceback method of exceptions:

raise Exception("foo occurred").with_traceback(tracebackobj)

These features are minimally described as part of the raise documentation.

All credit for this part of the answer should go to Vyctor, who first posted this information. I’m including it here only because this answer is stuck at the top, and Python 3 is becoming more common.

In Python 2

It’s annoyingly complex. The trouble with tracebacks is that they have references to stack frames, and stack frames have references to the tracebacks that have references to stack frames that have references to… you get the idea. This causes problems for the garbage collector. (Thanks to ecatmur for first pointing this out.)

The nice way of solving this would be to surgically break the cycle after leaving the except clause, which is what Python 3 does. The Python 2 solution is much uglier: you are provided with an ad-hoc function,sys.exc_info(), which only works inside the except clause. It returns a tuple containing the exception, the exception type, and the traceback for whatever exception is currently being handled.

So if you are inside the except clause, you can use the output of sys.exc_info() along with the traceback module to do various useful things:

>>> import sys, traceback
>>> def raise_exception():
...     try:
...         raise Exception
...     except Exception:
...         ex_type, ex, tb = sys.exc_info()
...         traceback.print_tb(tb)
...     finally:
...         del tb
... 
>>> raise_exception()
  File "<stdin>", line 3, in raise_exception

But as your edit indicates, you’re trying to get the traceback that would have been printed if your exception had not been handled, after it has already been handled. That’s a much harder question. Unfortunately, sys.exc_info returns (None, None, None) when no exception is being handled. Other related sys attributes don’t help either. sys.exc_traceback is deprecated and undefined when no exception is being handled; sys.last_traceback seems perfect, but it appears only to be defined during interactive sessions.

If you can control how the exception is raised, you might be able to use inspect and a custom exception to store some of the information. But I’m not entirely sure how that would work.

To tell the truth, catching and returning an exception is kind of an unusual thing to do. This might be a sign that you need to refactor anyway.


回答 1

Python 3.0 [PEP 3109]开始,内置类Exception具有__traceback__包含的属性traceback object(对于Python 3.2.3):

>>> try:
...     raise Exception()
... except Exception as e:
...     tb = e.__traceback__
...
>>> tb
<traceback object at 0x00000000022A9208>

问题是,在谷歌搜索__traceback__一段时间后,我发现只有几篇文章,但是没有一篇描述您是否或为什么应该使用__traceback__

但是,针对的Python 3文档raise指出:

通常会在引发异常并将其附加__traceback__为可写属性的情况下自动创建回溯对象。

因此,我认为它应该被使用。

Since Python 3.0[PEP 3109] the built in class Exception has a __traceback__ attribute which contains a traceback object (with Python 3.2.3):

>>> try:
...     raise Exception()
... except Exception as e:
...     tb = e.__traceback__
...
>>> tb
<traceback object at 0x00000000022A9208>

The problem is that after Googling __traceback__ for a while I found only few articles but none of them describes whether or why you should (not) use __traceback__.

However, the Python 3 documentation for raise says that:

A traceback object is normally created automatically when an exception is raised and attached to it as the __traceback__ attribute, which is writable.

So I assume it’s meant to be used.


回答 2

一种从Python 3中的异常对象以字符串形式获取回溯的方法:

import traceback

# `e` is an exception object that you get from somewhere
traceback_str = ''.join(traceback.format_tb(e.__traceback__))

traceback.format_tb(...)返回字符串列表。''.join(...)将他们连接在一起。有关更多参考,请访问:https : //docs.python.org/3/library/traceback.html#traceback.format_tb

A way to get traceback as a string from an exception object in Python 3:

import traceback

# `e` is an exception object that you get from somewhere
traceback_str = ''.join(traceback.format_tb(e.__traceback__))

traceback.format_tb(...) returns a list of strings. ''.join(...) joins them together. For more reference, please visit: https://docs.python.org/3/library/traceback.html#traceback.format_tb


回答 3

顺便说一句,如果您希望像在终端上看到的那样真正获得完整的追溯,则需要这样做:

>>> try:
...     print(1/0)
... except Exception as e:
...     exc = e
...
>>> exc
ZeroDivisionError('division by zero')
>>> tb_str = traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)
>>> tb_str
['Traceback (most recent call last):\n', '  File "<stdin>", line 2, in <module>\n', 'ZeroDivisionError: division by zero\n']
>>> print("".join(tb_str))
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

如果您使用format_tb上述答案,则建议您获得的信息较少:

>>> tb_str = "".join(traceback.format_tb(exc.__traceback__))
>>> print("".join(tb_str))
  File "<stdin>", line 2, in <module>

As an aside, if you want to actually get the full traceback as you would see it printed to your terminal, you want this:

>>> try:
...     print(1/0)
... except Exception as e:
...     exc = e
...
>>> exc
ZeroDivisionError('division by zero')
>>> tb_str = traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)
>>> tb_str
['Traceback (most recent call last):\n', '  File "<stdin>", line 2, in <module>\n', 'ZeroDivisionError: division by zero\n']
>>> print("".join(tb_str))
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

If you use format_tb as above answers suggest you’ll get less information:

>>> tb_str = "".join(traceback.format_tb(exc.__traceback__))
>>> print("".join(tb_str))
  File "<stdin>", line 2, in <module>

回答 4

有一个很好的理由是,回溯不存储在异常中。因为回溯保留对堆栈本地的引用,所以这将导致循环引用和(临时)内存泄漏,直到循环GC启动。(这就是为什么永远不要将回溯存储在局部变量中的原因。)

关于我,我唯一想到的就是您可以进行修补 stuff的全局变量,以便当它认为正在捕获时Exception,实际上是在捕获特殊类型,并且异常作为调用者传播给您:

module_containing_stuff.Exception = type("BogusException", (Exception,), {})
try:
    stuff()
except Exception:
    import sys
    print sys.exc_info()

There’s a very good reason the traceback is not stored in the exception; because the traceback holds references to its stack’s locals, this would result in a circular reference and (temporary) memory leak until the circular GC kicks in. (This is why you should never store the traceback in a local variable.)

About the only thing I can think of would be for you to monkeypatch stuff‘s globals so that when it thinks it’s catching Exception it’s actually catching a specialised type and the exception propagates to you as the caller:

module_containing_stuff.Exception = type("BogusException", (Exception,), {})
try:
    stuff()
except Exception:
    import sys
    print sys.exc_info()

排序查询集的好方法?-Django

问题:排序查询集的好方法?-Django

我想做的是这样的:

  • 获得得分最高的30位作者(Author.objects.order_by('-score')[:30]

  • 命令作者 last_name


有什么建议?

what I’m trying to do is this:

  • get the 30 Authors with highest score ( Author.objects.order_by('-score')[:30] )

  • order the authors by last_name


Any suggestions?


回答 0

关于什么

import operator

auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))

在Django 1.4及更高版本中,您可以通过提供多个字段进行订购。
参考:https : //docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

order_by(*字段)

默认情况下,a返回的结果由模型的Meta中QuerySetordering选项给出的排序元组排序。您可以使用order_by方法基于每个QuerySet重写此方法。

例:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

上面的结果将按score降序排列,然后按last_name升序排列。前面的负号"-score"表示降序。隐含升序。

What about

import operator

auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))

In Django 1.4 and newer you can order by providing multiple fields.
Reference: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

order_by(*fields)

By default, results returned by a QuerySet are ordered by the ordering tuple given by the ordering option in the model’s Meta. You can override this on a per-QuerySet basis by using the order_by method.

Example:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

The result above will be ordered by score descending, then by last_name ascending. The negative sign in front of "-score" indicates descending order. Ascending order is implied.


回答 1

我只是想说明一下内置解决方案(仅适用于SQL)并不总是最好的。最初,我认为因为Django的QuerySet.objects.order_by方法接受多个参数,所以您可以轻松地将它们链接起来:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

但是,它没有按您期望的那样工作。举例来说,首先是按得分排序的总统列表(选择前5名以便于阅读):

>>> auths = Author.objects.order_by('-score')[:5]
>>> for x in auths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

使用Alex Martelli的解决方案,该解决方案可准确提供排名前5位的人员last_name

>>> for x in sorted(auths, key=operator.attrgetter('last_name')): print x
... 
Benjamin Harrison (467)
James Monroe (487)
Gerald Rudolph (464)
Ulysses Simpson (474)
Harry Truman (471)

现在组合order_by调用:

>>> myauths = Author.objects.order_by('-score', 'last_name')[:5]
>>> for x in myauths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

如您所见,它与第一个结果相同,这意味着它无法按预期工作。

I just wanted to illustrate that the built-in solutions (SQL-only) are not always the best ones. At first I thought that because Django’s QuerySet.objects.order_by method accepts multiple arguments, you could easily chain them:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

But, it does not work as you would expect. Case in point, first is a list of presidents sorted by score (selecting top 5 for easier reading):

>>> auths = Author.objects.order_by('-score')[:5]
>>> for x in auths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

Using Alex Martelli’s solution which accurately provides the top 5 people sorted by last_name:

>>> for x in sorted(auths, key=operator.attrgetter('last_name')): print x
... 
Benjamin Harrison (467)
James Monroe (487)
Gerald Rudolph (464)
Ulysses Simpson (474)
Harry Truman (471)

And now the combined order_by call:

>>> myauths = Author.objects.order_by('-score', 'last_name')[:5]
>>> for x in myauths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

As you can see it is the same result as the first one, meaning it doesn’t work as you would expect.


回答 2

这是一种允许得分临界值的方法。

author_count = Author.objects.count()
cut_off_score = Author.objects.order_by('-score').values_list('score')[min(30, author_count)]
top_authors = Author.objects.filter(score__gte=cut_off_score).order_by('last_name')

这样一来,您在top_authors中可能会获得30多位作者,如果您的作者少于30位,则可以在此处找到min(30,author_count)

Here’s a way that allows for ties for the cut-off score.

author_count = Author.objects.count()
cut_off_score = Author.objects.order_by('-score').values_list('score')[min(30, author_count)]
top_authors = Author.objects.filter(score__gte=cut_off_score).order_by('last_name')

You may get more than 30 authors in top_authors this way and the min(30,author_count) is there incase you have fewer than 30 authors.


将Python字符串格式化与列表一起使用

问题:将Python字符串格式化与列表一起使用

s在Python 2.6.5中构造了一个字符串,该字符串将具有不同数量的%s令牌,这些令牌与list中的条目数匹配x。我需要写出格式化的字符串。以下内容不起作用,但表示我要执行的操作。在此示例中,有三个%s标记,并且列表具有三个条目。

s = '%s BLAH %s FOO %s BAR'
x = ['1', '2', '3']
print s % (x)

我希望输出字符串为:

1 BLAH 2 FOO 3 BAR

I construct a string s in Python 2.6.5 which will have a varying number of %s tokens, which match the number of entries in list x. I need to write out a formatted string. The following doesn’t work, but indicates what I’m trying to do. In this example, there are three %s tokens and the list has three entries.

s = '%s BLAH %s FOO %s BAR'
x = ['1', '2', '3']
print s % (x)

I’d like the output string to be:

1 BLAH 2 FOO 3 BAR


回答 0

print s % tuple(x)

代替

print s % (x)
print s % tuple(x)

instead of

print s % (x)

回答 1

您应该看一下python 的format方法。然后,您可以像这样定义格式字符串:

>>> s = '{0} BLAH BLAH {1} BLAH {2} BLAH BLIH BLEH'
>>> x = ['1', '2', '3']
>>> print s.format(*x)
'1 BLAH BLAH 2 BLAH 3 BLAH BLIH BLEH'

You should take a look to the format method of python. You could then define your formatting string like this :

>>> s = '{0} BLAH BLAH {1} BLAH {2} BLAH BLIH BLEH'
>>> x = ['1', '2', '3']
>>> print s.format(*x)
'1 BLAH BLAH 2 BLAH 3 BLAH BLIH BLEH'

回答 2

在此资源页面之后,如果x的长度变化,我们可以使用:

', '.join(['%.2f']*len(x))

为列表中的每个元素创建一个占位符x。这是示例:

x = [1/3.0, 1/6.0, 0.678]
s = ("elements in the list are ["+', '.join(['%.2f']*len(x))+"]") % tuple(x)
print s
>>> elements in the list are [0.33, 0.17, 0.68]

Following this resource page, if the length of x is varying, we can use:

', '.join(['%.2f']*len(x))

to create a place holder for each element from the list x. Here is the example:

x = [1/3.0, 1/6.0, 0.678]
s = ("elements in the list are ["+', '.join(['%.2f']*len(x))+"]") % tuple(x)
print s
>>> elements in the list are [0.33, 0.17, 0.68]

回答 3

这是一行代码。一个临时的答案,使用带有print()的format来迭代列表。

怎么样(Python 3.x):

sample_list = ['cat', 'dog', 'bunny', 'pig']
print("Your list of animals are: {}, {}, {} and {}".format(*sample_list))

在此处阅读有关使用format()的文档。

Here is a one liner. A little improvised answer using format with print() to iterate a list.

How about this (python 3.x):

sample_list = ['cat', 'dog', 'bunny', 'pig']
print("Your list of animals are: {}, {}, {} and {}".format(*sample_list))

Read the docs here on using format().


回答 4

由于我刚刚学到了这个很酷的东西(从格式字符串中索引到列表中),所以我添加了这个老问题。

s = '{x[0]} BLAH {x[1]} FOO {x[2]} BAR'
x = ['1', '2', '3']
print (s.format (x=x))

输出:

1 BLAH 2 FOO 3 BAR

但是,我仍然没有弄清楚如何进行切片(在格式字符串'"{x[2:4]}".format...中),并且很想弄清楚是否有人有想法,但是我怀疑您根本无法做到这一点。

Since I just learned about this cool thing(indexing into lists from within a format string) I’m adding to this old question.

s = '{x[0]} BLAH {x[1]} FOO {x[2]} BAR'
x = ['1', '2', '3']
print (s.format (x=x))

Output:

1 BLAH 2 FOO 3 BAR

However, I still haven’t figured out how to do slicing(inside of the format string '"{x[2:4]}".format...,) and would love to figure it out if anyone has an idea, however I suspect that you simply cannot do that.


回答 5

这是一个有趣的问题!处理可变长度列表的另一种方法是构建一个充分利用该.format方法和列表拆包的功能。在下面的示例中,我不使用任何特殊的格式,但是可以轻松地对其进行更改以满足您的需求。

list_1 = [1,2,3,4,5,6]
list_2 = [1,2,3,4,5,6,7,8]

# Create a function that can apply formatting to lists of any length:
def ListToFormattedString(alist):
    # Create a format spec for each item in the input `alist`.
    # E.g., each item will be right-adjusted, field width=3.
    format_list = ['{:>3}' for item in alist] 

    # Now join the format specs into a single string:
    # E.g., '{:>3}, {:>3}, {:>3}' if the input list has 3 items.
    s = ','.join(format_list)

    # Now unpack the input list `alist` into the format string. Done!
    return s.format(*alist)

# Example output:
>>>ListToFormattedString(list_1)
'  1,  2,  3,  4,  5,  6'
>>>ListToFormattedString(list_2)
'  1,  2,  3,  4,  5,  6,  7,  8'

This was a fun question! Another way to handle this for variable length lists is to build a function that takes full advantage of the .format method and list unpacking. In the following example I don’t use any fancy formatting, but that can easily be changed to suit your needs.

list_1 = [1,2,3,4,5,6]
list_2 = [1,2,3,4,5,6,7,8]

# Create a function that can apply formatting to lists of any length:
def ListToFormattedString(alist):
    # Create a format spec for each item in the input `alist`.
    # E.g., each item will be right-adjusted, field width=3.
    format_list = ['{:>3}' for item in alist] 

    # Now join the format specs into a single string:
    # E.g., '{:>3}, {:>3}, {:>3}' if the input list has 3 items.
    s = ','.join(format_list)

    # Now unpack the input list `alist` into the format string. Done!
    return s.format(*alist)

# Example output:
>>>ListToFormattedString(list_1)
'  1,  2,  3,  4,  5,  6'
>>>ListToFormattedString(list_2)
'  1,  2,  3,  4,  5,  6,  7,  8'

回答 6

与@neobot的答案相同,但更加现代和简洁。

>>> l = range(5)
>>> " & ".join(["{}"]*len(l)).format(*l)
'0 & 1 & 2 & 3 & 4'

The same as @neobot’s answer but a little more modern and succinct.

>>> l = range(5)
>>> " & ".join(["{}"]*len(l)).format(*l)
'0 & 1 & 2 & 3 & 4'

回答 7

x = ['1', '2', '3']
s = f"{x[0]} BLAH {x[1]} FOO {x[2]} BAR"
print(s)

输出是

1 BLAH 2 FOO 3 BAR
x = ['1', '2', '3']
s = f"{x[0]} BLAH {x[1]} FOO {x[2]} BAR"
print(s)

The output is

1 BLAH 2 FOO 3 BAR

格式化字符串时多次插入相同的值

问题:格式化字符串时多次插入相同的值

我有这种形式的字符串

s='arbit'
string='%s hello world %s hello world %s' %(s,s,s)

字符串中的所有%s都具有相同的值(即s)。有没有更好的书写方式?(而不是列出三遍)

I have a string of this form

s='arbit'
string='%s hello world %s hello world %s' %(s,s,s)

All the %s in string have the same value (i.e. s). Is there a better way of writing this? (Rather than listing out s three times)


回答 0

您可以使用Python 2.6和Python 3.x中提供的高级字符串格式

incoming = 'arbit'
result = '{0} hello world {0} hello world {0}'.format(incoming)

You can use advanced string formatting, available in Python 2.6 and Python 3.x:

incoming = 'arbit'
result = '{0} hello world {0} hello world {0}'.format(incoming)

回答 1

incoming = 'arbit'
result = '%(s)s hello world %(s)s hello world %(s)s' % {'s': incoming}

您可能需要阅读以下内容以了解:String Formatting Operations

incoming = 'arbit'
result = '%(s)s hello world %(s)s hello world %(s)s' % {'s': incoming}

You may like to have a read of this to get an understanding: String Formatting Operations.


回答 2

您可以使用格式的字典类型:

s='arbit'
string='%(key)s hello world %(key)s hello world %(key)s' % {'key': s,}

You can use the dictionary type of formatting:

s='arbit'
string='%(key)s hello world %(key)s hello world %(key)s' % {'key': s,}

回答 3

取决于您的意思更好。如果您的目标是消除冗余,则此方法有效。

s='foo'
string='%s bar baz %s bar baz %s bar baz' % (3*(s,))

Depends on what you mean by better. This works if your goal is removal of redundancy.

s='foo'
string='%s bar baz %s bar baz %s bar baz' % (3*(s,))

回答 4

>>> s1 ='arbit'
>>> s2 = 'hello world '.join( [s]*3 )
>>> print s2
arbit hello world arbit hello world arbit
>>> s1 ='arbit'
>>> s2 = 'hello world '.join( [s]*3 )
>>> print s2
arbit hello world arbit hello world arbit

回答 5

弦线

如果您正在使用Python 3.6+,则可以使用新的,f-strings它代表格式化的字符串,可以通过f在字符串的开头添加字符以将其标识为f字符串来使用它

price = 123
name = "Jerry"
print(f"{name}!!, {price} is much, isn't {price} a lot? {name}!")
>Jerry!!, 123 is much, isn't 123 a lot? Jerry!

使用f字符串的主要好处是它们更具可读性,可以更快,并且具有更好的性能:

每个人的熊猫资源:Python数据分析,作者Daniel Y. Chen

基准测试

毫无疑问,新f-strings方法更具可读性,因为您不必重新映射字符串,但是如前所述,它是否更快?

price = 123
name = "Jerry"

def new():
    x = f"{name}!!, {price} is much, isn't {price} a lot? {name}!"


def old():
    x = "{1}!!, {0} is much, isn't {0} a lot? {1}!".format(price, name)

import timeit
print(timeit.timeit('new()', setup='from __main__ import new', number=10**7))
print(timeit.timeit('old()', setup='from __main__ import old', number=10**7))
> 3.8741058271543776  #new
> 5.861819514350163   #old

运行1000万次测试似乎新f-strings的映射速度实际上更快。

Fstrings

If you are using Python 3.6+ you can make use of the new so called f-strings which stands for formatted strings and it can be used by adding the character f at the beginning of a string to identify this as an f-string.

price = 123
name = "Jerry"
print(f"{name}!!, {price} is much, isn't {price} a lot? {name}!")
>Jerry!!, 123 is much, isn't 123 a lot? Jerry!

The main benefits of using f-strings is that they are more readable, can be faster, and offer better performance:

Source Pandas for Everyone: Python Data Analysis, By Daniel Y. Chen

Benchmarks

No doubt that the new f-strings are more readable, as you don’t have to remap the strings, but is it faster though as stated in the aformentioned quote?

price = 123
name = "Jerry"

def new():
    x = f"{name}!!, {price} is much, isn't {price} a lot? {name}!"


def old():
    x = "{1}!!, {0} is much, isn't {0} a lot? {1}!".format(price, name)

import timeit
print(timeit.timeit('new()', setup='from __main__ import new', number=10**7))
print(timeit.timeit('old()', setup='from __main__ import old', number=10**7))
> 3.8741058271543776  #new
> 5.861819514350163   #old

Running 10 Million test’s it seems that the new f-strings are actually faster in mapping.


Python可以打印函数定义吗?

问题:Python可以打印函数定义吗?

在JavaScript中,可以打印出函数的定义。有没有办法在Python中完成此任务?

(只是在交互模式下玩,所以我想在没有open()的情况下读取模块。我只是很好奇。)

In JavaScript, one can print out the definition of a function. Is there a way to accomplish this in Python?

(Just playing around in interactive mode, and I wanted to read a module without open(). I was just curious).


回答 0

如果要导入功能,则可以使用inspect.getsource

>>> import re
>>> import inspect
>>> print inspect.getsource(re.compile)
def compile(pattern, flags=0):
    "Compile a regular expression pattern, returning a pattern object."
    return _compile(pattern, flags)

在交互式提示中起作用,但显然仅适用于导入的对象(不适用于交互式提示中定义的对象)。当然,只有在Python可以找到源代码的情况下它才会起作用(因此不能在内置对象,C库,.pyc文件等上找到)

If you are importing the function, you can use inspect.getsource:

>>> import re
>>> import inspect
>>> print inspect.getsource(re.compile)
def compile(pattern, flags=0):
    "Compile a regular expression pattern, returning a pattern object."
    return _compile(pattern, flags)

This will work in the interactive prompt, but apparently only on objects that are imported (not objects defined within the interactive prompt). And of course it will only work if Python can find the source code (so not on built-in objects, C libs, .pyc files, etc)


回答 1

如果您使用的是iPython,则可以使用function_name?获得帮助,并且function_name??可以打印出源代码。

If you’re using iPython, you can use function_name? to get help, and function_name?? will print out the source, if it can.


回答 2

这是我想出的方法:

    import inspect as i
    import sys
    sys.stdout.write(i.getsource(MyFunction))

这样可以取出换行符并很好地打印功能

This is the way I figured out how to do it:

    import inspect as i
    import sys
    sys.stdout.write(i.getsource(MyFunction))

This takes out the new line characters and prints the function out nicely


回答 3

尽管我通常会认为这inspect是一个很好的答案,但我不同意您无法获得解释器中定义的对象的源代码。如果使用dill.source.getsourcefrom dill,即使它们是交互式定义的,也可以获取函数和lambda的来源。它也可以从咖喱中定义的绑定或未绑定类方法和函数中获取代码。但是,如果没有封闭对象的代码,则可能无法编译该代码。

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 

While I’d generally agree that inspect is a good answer, I’d disagree that you can’t get the source code of objects defined in the interpreter. If you use dill.source.getsource from dill, you can get the source of functions and lambdas, even if they are defined interactively. It also can get the code for from bound or unbound class methods and functions defined in curries… however, you might not be able to compile that code without the enclosing object’s code.

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 

回答 4

help(function)得到的功能说明。

您可以help() 在此处了解更多信息。

Use help(function) to get the function description.

You can read more about help() here.


回答 5

您可以使用__doc__关键字:

#print the class description
print string.__doc__
#print function description
print open.__doc__

You can use the __doc__ keyword:

#print the class description
print string.__doc__
#print function description
print open.__doc__

回答 6

您可以__doc__在函数中使用,以hog()函数为例:您可以看到这样的用法hog()

from skimage.feature import hog

print hog.__doc__

输出将是:

Extract Histogram of Oriented Gradients (HOG) for a given image.
Compute a Histogram of Oriented Gradients (HOG) by

    1. (optional) global image normalisation
    2. computing the gradient image in x and y
    3. computing gradient histograms
    4. normalising across blocks
    5. flattening into a feature vector

Parameters
----------
image : (M, N) ndarray
    Input image (greyscale).
orientations : int
    Number of orientation bins.
pixels_per_cell : 2 tuple (int, int)
    Size (in pixels) of a cell.
cells_per_block  : 2 tuple (int,int)
    Number of cells in each block.
visualise : bool, optional
    Also return an image of the HOG.
transform_sqrt : bool, optional
    Apply power law compression to normalise the image before
    processing. DO NOT use this if the image contains negative
    values. Also see `notes` section below.
feature_vector : bool, optional
    Return the data as a feature vector by calling .ravel() on the result
    just before returning.
normalise : bool, deprecated
    The parameter is deprecated. Use `transform_sqrt` for power law
    compression. `normalise` has been deprecated.

Returns
-------
newarr : ndarray
    HOG for the image as a 1D (flattened) array.
hog_image : ndarray (if visualise=True)
    A visualisation of the HOG image.

References
----------
* http://en.wikipedia.org/wiki/Histogram_of_oriented_gradients

* Dalal, N and Triggs, B, Histograms of Oriented Gradients for
  Human Detection, IEEE Computer Society Conference on Computer
  Vision and Pattern Recognition 2005 San Diego, CA, USA

Notes
-----
Power law compression, also known as Gamma correction, is used to reduce
the effects of shadowing and illumination variations. The compression makes
the dark regions lighter. When the kwarg `transform_sqrt` is set to
``True``, the function computes the square root of each color channel
and then applies the hog algorithm to the image.

You can use the __doc__ in the function, take hog() function as example: You can see the usage of hog() like this:

from skimage.feature import hog

print hog.__doc__

The output will be:

Extract Histogram of Oriented Gradients (HOG) for a given image.
Compute a Histogram of Oriented Gradients (HOG) by

    1. (optional) global image normalisation
    2. computing the gradient image in x and y
    3. computing gradient histograms
    4. normalising across blocks
    5. flattening into a feature vector

Parameters
----------
image : (M, N) ndarray
    Input image (greyscale).
orientations : int
    Number of orientation bins.
pixels_per_cell : 2 tuple (int, int)
    Size (in pixels) of a cell.
cells_per_block  : 2 tuple (int,int)
    Number of cells in each block.
visualise : bool, optional
    Also return an image of the HOG.
transform_sqrt : bool, optional
    Apply power law compression to normalise the image before
    processing. DO NOT use this if the image contains negative
    values. Also see `notes` section below.
feature_vector : bool, optional
    Return the data as a feature vector by calling .ravel() on the result
    just before returning.
normalise : bool, deprecated
    The parameter is deprecated. Use `transform_sqrt` for power law
    compression. `normalise` has been deprecated.

Returns
-------
newarr : ndarray
    HOG for the image as a 1D (flattened) array.
hog_image : ndarray (if visualise=True)
    A visualisation of the HOG image.

References
----------
* http://en.wikipedia.org/wiki/Histogram_of_oriented_gradients

* Dalal, N and Triggs, B, Histograms of Oriented Gradients for
  Human Detection, IEEE Computer Society Conference on Computer
  Vision and Pattern Recognition 2005 San Diego, CA, USA

Notes
-----
Power law compression, also known as Gamma correction, is used to reduce
the effects of shadowing and illumination variations. The compression makes
the dark regions lighter. When the kwarg `transform_sqrt` is set to
``True``, the function computes the square root of each color channel
and then applies the hog algorithm to the image.

有趣好用的Python教程

退出移动版
微信支付
请使用 微信 扫码支付