如果您对熊猫:SettingWithCopyWarning和熊猫计划感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解熊猫:SettingWithCopyWarning的各种细节,并对熊猫计划进行
如果您对熊猫:SettingWithCopyWarning和熊猫计划感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解熊猫:SettingWithCopyWarning的各种细节,并对熊猫计划进行深入的分析,此外还有关于Beginners Guide to Getting Started with AS3 (Without Learning Flex)、Fixing "perl: warning: Setting locale failed."、iOS照片扩展finishContentEditingWithCompletionHandler:无法保存更改、Pandas 中 SettingwithCopyWarning 的原理和解决方案的实用技巧。
本文目录一览:- 熊猫:SettingWithCopyWarning(熊猫计划)
- Beginners Guide to Getting Started with AS3 (Without Learning Flex)
- Fixing "perl: warning: Setting locale failed."
- iOS照片扩展finishContentEditingWithCompletionHandler:无法保存更改
- Pandas 中 SettingwithCopyWarning 的原理和解决方案
熊猫:SettingWithCopyWarning(熊猫计划)
我想将Pandas
DataFrame
大于任意数(在这种情况下NaN
为100)的值替换为(因为如此大的值表示实验失败)。以前,我使用它来替换不需要的值:
sve2_all[sve2_all['' Hgtot ng/l''] > 100] = np.nan
但是,出现以下错误:
-c:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.Try using .loc[row_index,col_indexer] = value insteadC:\Users\AppData\Local\Enthought\Canopy32\User\lib\site-packages\pandas\core\indexing.py:346: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.Try using .loc[row_index,col_indexer] = value insteadself.obj[item] = s
从这个StackExchange问题来看,有时似乎可以忽略此警告,但是我不能很好地跟踪讨论,无法确定这是否适用于我的情况。警告基本上是让我知道我将覆盖我的某些值DataFrame
吗?
编辑:据我所知,一切都按其应有的方式进行。作为后续措施,我的替换值方法是否非标准?是否有更好的方法替换值?
答案1
小编典典如错误消息中所建议,您应该使用loc来执行此操作:
sve2_all.loc[sve2_all[''Hgtot ng/l''] > 100] = np.nan
该警告是来阻止你修改副本(在这里sve2_all[sve2_all['' Hgtot ng/l''] > 100]
是 潜在的
副本,如果是则进行任何修改不会改变原有的框架。这可能是因为它正确地工作在某些情况下,但大熊猫不能保证它会在所有的工作情况…使用风险自负(请警告自己!;))。
Beginners Guide to Getting Started with AS3 (Without Learning Flex)
senocular.com
-
Flash
- Source Files
- ActionScript
- Extensions
- Tutorials
-
Fireworks
- Source Files
- Extensions
- Tutorials
-
Dreamweaver
- Extensions
- Tutorials
-
Other
- About
- Contact
- Smilies
Tutorials,extensions,and source files for ActionScript,Flash,and other Adobe products.
Beginners Guide to Getting Started with AS3 (Without Learning Flex)
If you're anxIoUs to get started with ActionScript 3 but don't want to have to learn Flex or MXML,the form of XML Flex uses to design applications,this tutorial is for you. Here you will learn how to use the command line compiler (mxmlc.exe for the Windows platform) to compile and create SWF files that use ActionScript 3.
- ActionScript 3 Starter Files (102K)
Using or own Flash CS3? If so this tutorial might not be for you. Instead check out Getting Started with ActionScript 3.0 in Adobe Flash CS3.
Obtaining the Compiler
To create SWF files from ActionScript,you will need a compiler,the program that interprets ActionScript code and translates it into the machine code used in SWF files. If you have Flex Builder 2 installed,you already have mxmlc.exe,the compiler that does this for MXML and ActionScript 3 files. If not,you can get a copy of mxmlc.exe by installing Flex Builder or downloading the Flex SDK,both of which are available from http://www.adobe.com/go/flex_trial/.
Flex Builder: If you've installed Flex Builder,you can find mxmlc.exe in the following directory (this may vary for custom installations):
C:\Program Files\Adobe\Flex Builder 2\Flex SDK 2\bin\mxmlc.exe
Flex SDK: If you've downloaded the SDK,save it to any location on your hard drive. Then,from that location,you can find mxmlc.exe in
[save location of SDK]\bin\mxmlc.exe
mxmlc.exe in the bin directory
Note: Bear in mind that to view ActionScript 3-published SWFs,you will need the Flash 9 player. Players are included with the downloads above or can be found on http://www.adobe.com/go/getflashplayer. You may also need to make sure that your swf file are associated with the version 9 Player so that when you open them,they will play correctly in the correct (v9) player.
Note: Some screen shots may be from older versions of the SDK and/or source files.
About mxmlc.exe
mxmlc.exe is a launcher that runs the MXML and ActionScript 3 compiler that converts MXML files (.mxml) and ActionScript 3 files (.as) into published SWF files (for the purposes of this tutorial,we will be primarily concerned with ActionScript 3 files though the compiler handles both as well as some other file types used in the ultimate generation of the SWF). The real compiler is a Java jar file located in the lib directory of your Flex Builder/SDK install and not mxmlc.exe itself. Because of this,to work with the compiler you'll A) need to make sure you keep all of those files of which the compiler is dependant (i.e. dont go moving around just mxmlc.exe and expect it to work),and B) need to have the Java runtime environment installed on your system. If you've installed Flex Builder you won't have to worry about this since it will take care of this for you. If you just got the SDK,however,and haven't had Java installed on your computer,you can download and install the Java runtime environment from http://java.sun.com.
In the directory containing mxmlc.exe you may notice some other executables. compc.exe is for creating SWC files (pre-compiled component file),and fdb.exe is the command line debugger. Here we are sticking to just using mxmlc.exe which is all you need to get started using ActionScript 3.
Using mxmlc.exe
When running mxmlc.exe,you'll need to supply it with at least (and usually) one ActionScript 3 file to compile. This file serves as the primary application file for the published SWF. Any other external ActionScript 3 files this application file imports or references will automatically be compiled into the resulting SWF. Unlike the Flash authoring environment or Flex Builder,though,mxmlc.exe has no GUI (graphical user interface); it is a command line tool. Trying to run it by double clicking and opening the EXE will cause a command prompt to pop up which will do some quick evalutation and immediately close. For it to work,it needs an ActionScript (or MXML) file to compile. To do this you have a couple of options.
Drag and Drop: The easiest way to supply an ActionScript 3 file to mxmlc.exe is to just use explorer to drag an AS file onto the EXE (or a shortcut to it). mxmlc.exe will be called targeting that ActionScript 3 file and will use the default options to compile and save the SWF in the directory in which the AS file was located.
Compile with mxmlc.exe using drag and drop
If there are any problems with the compilation,such as a Syntax error in the ActionScript,a SWF will not be created and the command prompt will display the errors briefly,but immediately close once its finished not giving you enough time to read them.
Command Line: Using the command line,you can run mxmlc.exe for any file(s) with any configuration variables or options you need and be able to keep the prompt open for errors and other messages. You can open a command line prompt by typing cmd into the Windows Run dialog (Windows Key+R) and hitting enter or running Start > Programs > Accessories > Command Prompt. In the command line,you'll need to be able to reference both mxmlc.exe and your target AS file either absolutely or relatively from the current directory displayed by the command prompt. An easy way to do this,no matter what directory your command line is in is,again,using drag and drop. First drag mxmlc.exe into the command line,hit the space bar,and drag your AS file into the command line.
Command line calling mxmlc.exe
Note: Paths with spaces in them will need to be encased in quotes.
Hit enter and mxmlc.exe will compile the provided AS file in the same manner it would if you dragged the AS file onto the EXE only in the case of errors or other messages the command prompt window will remain open so that you can read them.
With just the ActionScript file,mxmlc.exe is called with one argument assigned to its default option (-file-specs). The command line also allows you to specify other options that can help you modify the behavior of the mxmlc.exe call. A list of these options are as follows:
-benchmark | output performance benchmark |
-compiler.accessible | alias -accessible generate an accessible SWF |
-compiler.actionscript-file-encoding <string> | alias -actionscript-file-encoding specifies actionscript file encoding. If there is no BOM in the AS3 source files,the compiler will use this file encoding. |
-compiler.allow-source-path-overlap | alias -allow-source-path-overlap (advanced) |
-compiler.as3 | alias -as3 uses the AS3 compatibility mode. default is true. Either -as3 or -es3 must be 'true'. |
-compiler.context-root <context-path> | alias -context-root path to replace {context.root} tokens for service channel endpoints |
-compiler.debug | alias -debug |
-compiler.defaults-css-url <string> | alias -defaults-css-url (advanced) |
-compiler.doc | alias -doc (advanced) |
-compiler.es3 | alias -es3 uses the ES3 compatibility mode. default is false. |
-compiler.external-library-path [path-element] [...] | alias -el list of SWC files or directories to compile against but to omit from linking (repeatable) |
-compiler.fonts.languages.language-range <lang> <range> | alias -language-range a range to restrict the number of font glyphs embedded into the SWF (advanced,repeatable) |
-compiler.fonts.managers [manager-class] [...] | alias -managers Compiler font manager classes,in policy resolution order (advanced) |
-compiler.fonts.max-cached-fonts <string> | alias -max-cached-fonts (advanced) |
-compiler.fonts.max-glyphs-per-face <string> | alias -max-glyphs-per-face (advanced) |
-compiler.fonts.system-search-path [path-element] [...] | alias -system-search-path (advanced,repeatable) |
-compiler.headless-server | alias -headless-server a flag to set when Flex is running on a server without a display (advanced) |
-compiler.include-libraries [library] [...] | alias -include-libraries a list of libraries (SWCs) to completely include in the SWF (repeatable) |
-compiler.incremental | alias -incremental enables incremental compilation |
-compiler.keep-all-type-selectors | alias -keep-all-type-selectors disables the pruning of unused type selectors (advanced) |
-compiler.keep-generated-actionscript | alias -keep save temporary source files generated during MXML compilation (advanced) |
-compiler.library-path [path-element] [...] | alias -l list of SWC files or directories that contain SWC files (repeatable) |
-compiler.locale <string> | alias -locale specifies the locale for internationalization |
-compiler.namespaces.namespace <uri> <manifest> | alias -namespace Specify a URI to associate with a manifest of components for use as MXML elements (repeatable) |
-compiler.optimize | alias -optimize Enable post-link SWF optimization |
-compiler.profile | alias -profile generate a movie that is suitable for performance profiling |
-compiler.services <filename> | alias -services path to Flex Data Services configuration file |
-compiler.show-binding-warnings | alias -show-binding-warnings toggle whether warnings generated from data binding code are displayed |
-compiler.show-coach-warnings | alias -show-coach-warnings runs the AS3 compiler in a mode that detects legal but potentially incorrect code |
-compiler.show-dependency-warnings | alias -show-dependency-warnings show warnings when dependencies cannot be determined at compile time (advanced) |
-compiler.show-deprecation-warnings | alias -show-deprecation-warnings toggle whether the use of deprecated APIs generates a warning |
-compiler.source-path [path-element] [...] | alias -sp list of path elements that form the roots of ActionScript class hierarchies (repeatable) |
-compiler.strict | alias -strict runs the AS3 compiler in strict error checking mode. strict must be 'false' when es3 is 'true'. |
-compiler.theme [filename] [...] | alias -theme list of CSS or SWC files to apply as a theme (repeatable) |
-compiler.use-resource-bundle-Metadata | alias -use-resource-bundle-Metadata |
-compiler.verbose-stacktraces | alias -verbose-stacktraces save callstack information to the SWF for debugging (advanced) |
-compiler.warn-array-tostring-changes | alias -warn-array-tostring-changes (advanced) |
-compiler.warn-assigning-undefined-to-non-object-type | alias -warn-assigning-undefined-to-non-object-type (advanced) |
-compiler.warn-bad-type-cast | alias -warn-bad-type-cast (advanced) |
-compiler.warn-bad-undefined-comparision | alias -warn-bad-undefined-comparision (advanced) |
-compiler.warn-boolean-constructor-with-no-args | alias -warn-boolean-constructor-with-no-args (advanced) |
-compiler.warn-class-is-sealed | alias -warn-class-is-sealed (advanced) |
-compiler.warn-constructor-returns-value | alias -warn-constructor-returns-value (advanced) |
-compiler.warn-deprecated-event-handler-error | alias -warn-deprecated-event-handler-error (advanced) |
-compiler.warn-deprecated-function-error | alias -warn-deprecated-function-error (advanced) |
-compiler.warn-deprecated-property-error | alias -warn-deprecated-property-error (advanced) |
-compiler.warn-duplicate-func-def | alias -warn-duplicate-func-def (advanced) |
-compiler.warn-for-var-in-changes | alias -warn-for-var-in-changes (advanced) |
-compiler.warn-function-parameter-declared-as-void | alias -warn-function-parameter-declared-as-void (advanced) |
-compiler.warn-math-expressions-treat-null-like-zero | alias -warn-math-expressions-treat-null-like-zero (advanced) |
-compiler.warn-missing-namespace-decl | alias -warn-missing-namespace-decl (advanced) |
-compiler.warn-no-constructor | alias -warn-no-constructor (advanced) |
-compiler.warn-no-explicit-super-call-in-constructor | alias -warn-no-explicit-super-call-in-constructor (advanced) |
-compiler.warn-no-type-decl | alias -warn-no-type-decl (advanced) |
-compiler.warn-scoping-change-in-this | alias -warn-scoping-change-in-this (advanced) |
-compiler.warn-super-only-works-for-class-objects | alias -warn-super-only-works-for-class-objects (advanced) |
-compiler.warn-undefined-function | alias -warn-undefined-function (advanced) |
-compiler.warn-undefined-reference | alias -warn-undefined-reference (advanced) |
-compiler.warn-var-hidden-by-function | alias -warn-var-hidden-by-function (advanced) |
-compiler.warn-wrong-arg-type | alias -warn-wrong-arg-type (advanced) |
-compiler.warn-wrong-number-of-args | alias -warn-wrong-number-of-args (advanced) |
-compiler.warn-xml-class-has-changed | alias -warn-xml-class-has-changed (advanced) |
-debug-password <string> | the password to include in debuggable SWFs (advanced) |
-default-background-color <int> | default background color (may be overridden by the application code) (advanced) |
-default-frame-rate <int> | default frame rate to be used in the SWF. (advanced) |
-default-script-limits <max-recursion-depth> <max-execution-time> | default script execution limits (may be overridden by root attributes) (advanced) |
-default-size <width> <height> | default application size (may be overridden by root attributes in the application) (advanced) |
-dump-config <filename> | write a file containing all currently set configuration values in a format suitable for use as a flex config file (advanced) |
-externs [symbol] [...] | a list of symbols to omit from linking when building a SWF (advanced, repeatable) |
-file-specs [path-element] [...] | a list of source files to compile,the last file specified will be used as the target application (repeatable,default variable) |
-frames.frame [label] [classname] [...] | alias -frame A SWF frame label with a sequence of classnames that will be linked onto the frame. (advanced,repeatable) |
-help [keyword] [...] | keywords are 'Syntax','list','advanced','aliases','details',or a search term |
-includes [symbol] [...] | a list of symbols to always link in when building a SWF (advanced, repeatable) |
-lazy-init | Enable/disable ABC bytecode lazy initialization (advanced) |
-licenses.license <product> <serial-number> | alias -license (repeatable) |
-link-report <filename> | Output a XML-formatted report of all deFinitions linked into the application. (advanced) |
-load-config <filename> | load a file containing configuration options (repeatable) |
-load-externs <filename> | an XML file containing <def>,<pre>,and <ext> symbols to omit from linking when building a SWF (advanced,repeatable) |
-Metadata.contributor <name> | alias -contributor A contributor's name to store in the SWF Metadata (repeatable) |
-Metadata.creator <name> | alias -creator A creator's name to store in the SWF Metadata (repeatable) |
-Metadata.date <text> | alias -date The creation date to store in the SWF Metadata |
-Metadata.description <text> | alias -description The default description to store in the SWF Metadata |
-Metadata.language <code> | alias -language The language to store in the SWF Metadata (i.e. EN,FR) (repeatable) |
-Metadata.localized-description <text> <lang> | alias -localized-description A localized RDF/XMP description to store in the SWF Metadata (repeatable) |
-Metadata.localized-title <title> <lang> | alias -localized-title A localized RDF/XMP title to store in the SWF Metadata (repeatable) |
-Metadata.publisher <name> | alias -publisher A publisher's name to store in the SWF Metadata (repeatable) |
-Metadata.title <text> | alias -title The default title to store in the SWF Metadata |
-output <filename> | alias -o the filename of the SWF movie to create |
-raw-Metadata <text> | XML text to store in the SWF Metadata (overrides Metadata.* configuration) (advanced) |
-resource-bundle-list <filename> | (advanced) |
-runtime-shared-libraries [url] [...] | alias -rsl a list of runtime shared library URLs to be loaded before the application starts (repeatable) |
-use-network | toggle whether the SWF is flagged for access to network resources |
-version | display the build version of the program |
-warnings | toggle the display of warnings |
These options follow the path to the application in the command prompt. They are preceded by hyphens and are usually followed by one or more space separated values. Note: you can obtain these options in the command list by running: mxmlc.exe -help list advanced details
Command to mxmlc.exe with additional options.
Batch (.bat) Files (preferred): Batch files are another alternative. They allow you to save command line commands to a text file that runs like an application. Using a batch file you can save your call to mxmlc.exe with any number of options and run those commands just by double clicking and launching a BAT. This tends to be the most useful approach to using mxmlc.exe. In fact,you may notice in the samples provided with both the Flex Builder and the SDK that there are build.bat files which are used to compile the project with mxmlc.exe.
Batch file launching mxmlc.exe
Using make.bat
In the source files provided with this tutorial you'll find a make.bat file. This batch file doesn't run mxmlc.exe to compile your ActionScript 3 files. Instead it was created to help you easily create the batch files that do. To use make.bat,just drag an AS file onto it. Then,a new batch file will be created with the name of your AS file that,when launched,will run mxmlc.exe and compile your AS file into a SWF. Additionally,the first time you run make.bat,it will automatically launch the BAT it creates for you. Before using make.bat,be sure to open it up in a text editor so you can set some variables letting you specify where your mxmlc.exe is located and set command line options. Otherwise the BAT files it creates will not function properly.
Editing make.bat Options
Create BAT with make.bat using drag and drop
When running a BAT created with make.bat,your AS file will be compiled using mxmlc.exe using the path you specified inside make.bat. If there are errors,the command line running mxmlc.exe will remain open showing those errors until you hit a key to continue,closing the prompt. In this case,no SWF is created and any pre-existing SWF will be deleted (the BAT does this,not mxmlc.exe). If the compile was successful,a new SWF will be created,overwriting any pre-existing SWF with the same name and it will automatically open for you to view. A command prompt will remain open in the background but will close when the SWF is closed.
Note: Using the -output (-o) option for mxmlc.exe to change the name of the published SWF,may cause make.bat-generated BAT files to function improperly
Working With ActionScript 3
Using mxmlc.exe doesn't help if you don't kNow ActionScript 3. Adobe labs (http://labs.adobe.com) has many resources to get you started with AS3. Some of the more important are the migration guide (http://www.adobe.com/go/AS2toAS3) and the language reference (http://www.adobe.com/go/AS3LR). These are good references but may not be the best for when you're just starting off.
I think its often helpful to start with the lowest common denominator–something that is very basic and gets you familiar with the minimum requirements for any kind of functionality. For that,we can create a simple class that has only what is necessary to get compiled by mxmlc.exe. Such a file has already been created for you and can found in the source files with the name BareBones.as. It consists of the following:
package { import flash.display.Sprite; public class BareBones extends Sprite {} }
To quickly publish it using mxmlc.exe,just drag BareBones.as onto the mxmlc.exe file. The BareBones.swf will be automatically created for you with BareBones.as (there should be no errors so the messages in the command prompt are not important). To publish it with the help of make.bat,drag BareBones.as onto make.bat to create BareBones.bat (be sure that you changed the path in make.bat to point to your the location of mxmlc.exe on your system). The new BAT will automatically run compiling BareBones.as and running the resulting SWF. When you want to compile BareBones.as again,just double-click and open BareBones.bat (there will be no need to run make again).
Published BareBones.swf
The SWF,as you might have expected,is empty.
Taking a closer look at BareBones.as you'll notice that it consists of a single empty class file. This class,BareBones,extends the internal Sprite class which is imported from the flash.display package. To make use of the Sprite class at all in ActionScript 3,the import statement is required unlike in ActionScript 2 where it served only as a path shortener. Both the import statement and the class are contained within another block of code identified with the keyword package.
The package block is new to ActionScript 3. It lets you identify members of a package or groups of public code that can be imported into and used by other classes. If BareBones were in the com.senocular package,it would be saved as com/senocular/BareBones.as and be written as:
package com.senocular { import flash.display.Sprite; public class BareBones extends Sprite {} }
Unlike ActionScript 2,the package is no longer part of the class deFinition. Instead it is part of this new package block deFinition. Public classes not technically within a package still need to exist within a package code block as seen with the original BareBones class.
Was:
class path.path.ClassName { }
Now:
package path.path { class ClassName { } }
When published as a SWF,the BareBones class is associated with what in earlier versions of ActionScript was kNown as _root,or essentially the main timeline. This applies to all classes being published as the application class in mxmlc.exe. In order for that class to successfully have that association,it needs to be of the correct type and that means that it needs to be a subclass of Sprite or any other class derived from the Sprite class such as MovieClip (in case you were wondering,a Sprite is basically a movie clip without a timeline and frames). If you have a application class compiled by mxmlc.exe that is not derived from Sprite,you will get a runtime error when the SWF is played.
SWF root runtime error
As the root object,your class is immediately instantiated and that instance is added to the stage object in Flash. With that instantiation,the application class constructor is called and you have a starting place for your ActionScript 3 program to begin. Example:
package { import flash.display.Sprite; public class BareBones extends Sprite { public function BareBones(){ // begin coding here } } }
More will be covered about the structure of ActionScript 3 classes a little later on. First,lets look into making a viable example that will be capable of making something appear on the screen.
display Objects in ActionScript 3
Objects you can see in the Flash player are kNown as display objects and are derived from the displayObject class. Such classes include,but are not limited to: Sprite,MovieClip (which is a subclass of Sprite),TextField,Bitmap,and Shape. All displayObject classes inherit from Eventdispatcher so are inherently event-capable. In addition,the Sprite,MovieClip,and TextField classes (along with some others) inherit from the InteractiveObject class meaning they can recieve events from the mouse and keyboard such as mouSEOver,click,and keyUp. Sprite and MovieClip also inherit from a class called displayObjectContainer meaning that they can contain other display objects within them. The application class of a SWF is derived from the Sprite class so it too is a displayObjectContainer. As such,it can add other classes to it as children.
The management of display objects in ActionScript 3 has completely changed. No longer do you use attachMovie,createEmptyMovieClip,or createTextField etc to create new MovieClip or TextField instances. Instead,you use the new keyword to create new instances of these objects and then add them to a displayObjectContainer using the addChild (or similar) method. If not added to a displayObjectContainer,the objects will exist and can be manipulated but are never seen as they will exist only in code. Once they are added to a displayObjectContainer,they can be easily removed or even added to some other displayObjectContainer at your leisure. The methods responsible for adding or removing instances from a displayObjectContainer include:
- addChild
- addChildAt
- removeChild
- removeChildAt
For more information on these and other related methods see the DisplayObjectContainer class documentation.
HelloWorld.as
The infamous "Hello World" example in ActionScript 3; creating and displaying the text "Hello World!":
package { import flash.display.Sprite; import flash.text.TextField; public class HelloWorld extends Sprite { public function HelloWorld() { var display_txt:TextField = new TextField(); display_txt.text = "Hello World!"; addChild(display_txt); } } }
Notice that the textfield used to display the text was created with new TextField and not createTextField as it would in prevIoUs versions of ActionScript. This textfield remained solely in code until addChild was used to attach it to the root HelloWorld class instance. Publish this as a SWF and you get the following:
HelloWorld.swf
Was:
MovieClip.createTextField();
Now:
displayObjectContainer.addChild(new TextField());
Graphics and the Drawing API
With ActionScript 3 also came some changes to the vector drawing API. Not only are there a couple of new methods such as drawCircle and drawRect,but the API is also no longer associated directly with MovieClip instances. Instead,the drawing API is Now used on Graphics class instances. Those display objects which support dynamic drawings such as MovieClip,Sprite,and Shape Now have graphics properties which are Graphics instances the drawing API is to be used with. When drawings are made within the graphics objects,they appear in the display object below any children that may have been added to them (assuming they are also displayObjectContainers,of which the Shape class is not).
As a Sprite,an application class will have a graphics property which can be used with the drawing API for the inclusion of dynamic drawings. As an example,see the Rectangles class:
package { import flash.display.Sprite; import flash.display.Shape; import flash.display.Graphics; public class Rectangles extends Sprite { public function Rectangles() { drawColoredRectIn(graphics,0xFF0000); var rect:Shape = new Shape(); drawColoredRectIn(rect.graphics,0xFFFF00); rect.x = 50; rect.y = 50; addChild(rect); } private function drawColoredRectIn(target:Graphics,color:int):void { target.linestyle(1,0x000000); target.beginFill(color); target.drawRect(0,100,100); } } }
Results:
Rectangles.swf
Note that drawings within the graphics object of a displayObject instance appear below children of that instance.
Was:
MovieClip.linestyle();
Now:
displayObject.graphics.linestyle();
Embedding Assets Within a SWF
Without the Flash IDE,there is no way to import assets into your source files. Your source files are,afterall,just ActionScript text at this point. However,mxmlc.exe will recognize Meta tags within the ActionScript that allow you to embed assets into the published swf and have those assets accessible as a custom class. The Meta tag allowing you to do this is Embed Meta tag.
The Embed Meta tag is used to grab assets from an external source (identified with a source value) and embeds them in the SWF when published. You would place an Embed Meta tag over a class variable that is typed as a class that would be used to represent the asset being embedded. Then,to create an instance of that object,you would use new in conjunction with the variable defined as that class.
The EmbedAssets class embeds both an image and a SWF (created in Flash 8) and assigns them to class properties. These class properties are then instantiated and added as children of the main application instance.
package { import flash.display.Sprite; public class EmbedAssets extends Sprite { [Embed(source="images/trophy.png")] private var TrophyImage:Class; [Embed(source="swfs/satdish.swf")] private var SatelliteAnimation:Class; public function EmbedAssets() { addChild(new SatelliteAnimation()); addChild(new TrophyImage()); } } }
As embedded images/animations (or sounds if you required them),these assets are immediately available to the movie when it loads into the player. Alternatively,you can use the Loader class to load external assets at runtime instead of embedding them in the SWF. See the LoadImage class in the source files for an example of this.
Event Handling
If you are familiar with the event model used by V2 components with Flash MX 2004 and Flash 8,you shouldn't have a problem with event handling in ActionScript 3. All events in ActionScript 3 are Now handled through the Eventdispatcher class. There are no more "on" event methods and no more addListener for objects like Mouse and Stage. Every event handler created will be associated with an event through addEventListener()
; Note: There is no longer a need for the Delegate class used in ActionScript 2 since listener functions maintain their original scope.
Many display objects like Sprite,and TextField inherit from the InteractiveObject class which means they receive events like rollover,mouseDown,and click among others. For more see the InteractiveObject documentation. Some of these events are a little different than those of ActionScript 1 and 2,but they ultimately allow for more control. See BallToss.as for an example:
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Rectangle; public class BallToss extends Sprite { private var ball:TossableBall; private var lastMouse:Point = new Point(); private var mouseMoved:Point = new Point(); public function BallToss() { var bounds:Rectangle = new Rectangle(0,stage.stageWidth,stage.stageHeight); ball = new TossableBall(50,bounds); ball.x = bounds.x + bounds.width/2; ball.y = bounds.y + bounds.height/2; addChild(ball); ball.addEventListener(MouseEvent.MOUSE_DOWN,grabBall); ball.addEventListener(MouseEvent.MOUSE_UP,releaseBall); } private function grabBall(evt:MouseEvent):void { ball.toss(new Point(0,0)); ball.startDrag(); lastMouse = new Point(mouseX,mouseY); addEventListener(Event.ENTER_FRAME,moveBall); moveBall(new Event(Event.ENTER_FRAME)); } private function releaseBall(evt:MouseEvent):void { ball.stopDrag(); ball.toss(mouseMoved); removeEventListener(Event.ENTER_FRAME,moveBall); } private function moveBall(evt:Event):void { var currMouse:Point = new Point(mouseX,mouseY); mouseMoved = currMouse.subtract(lastMouse); lastMouse = currMouse; } } } import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.geom.Rectangle; class TossableBall extends Sprite { private var bounds:Rectangle; private var vector:Point = new Point(); private var friction:Number = .95; public function TossableBall(size:Number,throwBounds:Rectangle) { bounds = throwBounds; graphics.linestyle(1); graphics.beginFill(0xFF8000); graphics.drawCircle(0,size/2); addEventListener(Event.ENTER_FRAME,soar); } public function toss(tossvector:Point):void { vector = tossvector; } private function soar(evt:Event):void { x += vector.x; y += vector.y; var shapeBounds:Rectangle = getBounds(parent); if (shapeBounds.left < bounds.left) { vector.x = Math.abs(vector.x); }else if (shapeBounds.right > bounds.right) { vector.x = -Math.abs(vector.x); } if (shapeBounds.top < bounds.top) { vector.y = Math.abs(vector.y); }else if (shapeBounds.bottom > bounds.bottom) { vector.y = -Math.abs(vector.y); } vector.x *= friction; vector.y *= friction; } }
Grab the ball and toss it with your mouse. As an InteractiveObject,the ball can receive mouse events and as a displayObject receives the enterFrame event. Note that the event strings for these events are available within the Event and MouseEvent classes as constants.
Was:
MovieClip.onPress = function(){ }
Now:
InteractiveObject.addListener("mouseDown",mouseDownHandler); ... function mouseDownHandler(){ }
More On ActionScript 3 Class Structure
You may have noticed something new with BallToss.as. The BallToss class defined is within the package code block,but there exists another class,TossableBall that is also defined within that same file outside of that block. In ActionScript 3,you have the option of defining additional helper classes in the same file. These classes would be placed outside the packages block and would only be accessible to classes within that file (internal access). The only class that is accessible outside that file is the main class within package block. The following class,HelperClasses,has 2 classes defined outside its packages block. These classes are accessible to all classes within the file,but not to any other classes outside of the file.
package { import flash.display.Sprite; public class HelperClasses extends Sprite { private var toyBuilder:SantasHelper; public function HelperClasses(){ toyBuilder = new SantasHelper(); } } } class Elf {} class SantasHelper extends Elf {}
The package block can also be used to define functions,not just classes. This would allow you to create functions not associated with any class or instance.
// CallPackagedFunction.as package { import flash.display.Sprite; public class CallPackagedFunction extends Sprite { public function CallPackagedFunction() { PackagedFunction(graphics); } } }
// PackagedFunction.as package { import flash.display.Graphics; public function PackagedFunction(target:Graphics):void { target.linestyle(0); target.lineto(100,100); } }
Notice that with the CallPackageFunction class,import was not needed for PackagedFunction. This is true for all classes or functions defined in unnamed packages. Those within actual pacakges would need to be imported using the import statement in order for the compiler to obtain the class being used.
Additional Notes Transitioning From ActionScript 2
There are a lot of changes in ActionScript 3 with the introduction of a brand spanking new virtual machine. Though there are many similarities,ActionScript 3 is not the same ActionScript 2 you are used to. The following will help you get used to some of the changes and avoid common pitfalls:
Member Access: No longer is member access restricted to just public and private (which was essentially protected). ActionScript 3 Now supports public
,private
(truely private),protected
,and internal
(default).
override: When you wish to extend another class with your own and override methods of the superclass,you are Now required to use the override
keyword
public class myClip extends MovieClip { override public function play():void { } }
Methods you override cannot be private and they must use the exact method signature. In other words,if the original method had two parameters,so should the method overriding it.
const/final: A new const
deFinition keyword Now allows you to create constants,or values that cannot be changed. The new final
keyword lets you create classes or methods within classes that cannot be extended or overridden.
final public class myClass { } public const COUNT_VAR:Number = 5; final public function myMethod():void { }
Data Typing: You should Now type all members. If a member is allowed any type,then type it using the *
special type. Any non-constructor method or function that does not have a return value should be typed as void
.
var myNum:Number; var myVar:*;
void: The Void type is Now lowercase (void
). Also,you no longer require void in a function parameter parameter list if a function accepts no arguments
function myFunction():void { }
int/uint: int
and uint
(unsigned int,or int that cannot be negative) are new data types for whole numbers or numbers that cannot have decimal values. When applicable (such as in loops),these types should be used in favor of the Number
type because of their improved efficiency.
Default Values: Some variable types Now how default values if one is not provided for them. This includes:
Number: NaN
int: 0
uint: 0
Boolean: false
Variables referenced but not defined or declared (defined without a default value) are seen as undefined. Other declared variables are given a default value of null unless an Object (non-core objects),then they are undefined. Note: Once declared Objects are the only types that can even store the value undefined. Also note,to check for an undeclared Number variable you should use isNaN()
.
Parameters/Arguments: Function parameters can Now have optional default values. If a parameter is not given a default value,it is seen as being required for that function. If you require an optional number of arguments,you would use the ... (rest) parameter. The ... (rest) parameter creates an array of all optional arguments passed to the function following the last explicit argument value (if defined). The format is three periods followed by the name of the array to hold any additional,optional arguments.
public function main():void { usingOptional(1); // usingOptional(); <- wrong - first parameter required usingRest(1,2,3,4); } private function usingOptional(required:Number,optional:String = "default"):void { trace(required); // 1 trace(optional); // "default" } private function usingRest(required:Number,... optionalArgs):void { trace(required); // 1 trace(optionalArgs); // [2,4] }
Enumeration/Iteration/Property checks: A new for each
statement has been added to iterate over an objects properties.
for each (variableIterant in object){ }
You can also use the in
operator to see if an object contains a certain property. The in
operator applies to both instance properties and inherited (prototype) properties.
if ("PI" in Math) { ... // true
To see only properties specific to that object instance and those not in the prototype,use Object.hasOwnProperty("property");
You can also use Object.propertyIsEnumerable("property")
to see if the property will reveal itself in enumeration.
Some of this information and more can be found on the ActionScript 3 Learning Tips and ActionScript 3 FAQ pages. Additional information can be found in the ActionScript 3 Language Reference.
Other Resources (in the Source Files)
EasyButton: The EasyButton class is an example of a button that was created from extending the SimpleButton class. Extending SimpleButton is the easiest way to make buttons with the most basic functionality in ActionScript 3. You can add an EasyButton to your class using:
var myButton:EasyButton = new EasyButton("Click Me"); addChild(myButton);
where "Click Me" represents the text displayed by the button. Then you assign an event handler to the button using addEventListener:
myButton.addEventListener("click",myClickMethod);
If you attempt to make your own,more complex button,you would want to use the Sprite class. However,be sure to set its mouseChildren property to false. Otherwise you may experience unexpected mouse event calls.
Output panel: Output.as is a class that creates an output panel on your main stage to be used for tracing and debugging variable values. It works much like trace in the Flash authoring environment only the output panel is in the SWF itself and you will need to call Output.trace()
to send values to it (as opposed to simply trace). In order to make use of Output.as,simply call
stage.addChild(new Output(stage));
in the constructor of your application ActionScript class. This will create the Output panel on the main stage and allow you yo trace values to it using Output.trace();
You can clear the output panel using Output.clear();
See SimpleOutputUsage.as for an example using the output panel and some EasyButtons.
SimpleOutputUsage.swf
Trevor McCauley ©2009
Fixing "perl: warning: Setting locale failed."
错误提示:
perl: warning: Setting locale failed.perl: warning: Please check that your locale settings:
LANGUAGE = "en_US:en",
LC_ALL = (unset),
LC_PAPER = "en_US",
LC_ADDRESS = "en_US",
LC_MONETARY = "en_US",
LC_NUMERIC = "en_US",
LC_TELEPHONE = "en_US",
LC_IDENTIFICATION = "en_US",
LC_MEASUREMENT = "en_US",
LC_TIME = "en_US",
LC_NAME = "en_US",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
解决办法:
最后:reboot
iOS照片扩展finishContentEditingWithCompletionHandler:无法保存更改
一切正常,但按完成后,无法保存图像.
标准完成处理程序代码:
- (void)finishContentEditingWithCompletionHandler:(void (^)(PHContentEditingOutput *))completionHandler { // Update UI to reflect that editing has finished and output is being rendered. // Render and provide output on a background queue. dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0),^{ PHContentEditingOutput *output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input]; NSError* error = nil; NSData *renderedJPEGData = UIImageJPEGRepresentation(filtered_ui_image,1.0); assert(renderedJPEGData != nil); //BOOL written_well = [renderedJPEGData writetoURL:output.renderedContentURL atomically:YES]; BOOL written_well = [renderedJPEGData writetoURL:output.renderedContentURL options:NSDataWritingAtomic error:&error]; assert(written_well); // Call completion handler to commit edit to Photos. completionHandler(output); }); }
renderedJPEGData不是nil,
错误是nil,因此函数[NSData writetoURL]成功,
written_well是,
逐行调试时,块完成后会出现一个警告:
output.renderedContentURL是/private/var/mobile/Containers/Data/PluginKitPlugin/509C1A04-D414-4DB7-B1E6-83C47FC88BC9/tmp/blah_blah_name.JPG
所以,我有权限,调试显示没有错误,我可以尝试检测问题的原因是什么?
解决方法
附加文件:https://developer.apple.com/reference/photos/phcontenteditingoutput/1518684-adjustmentdata
PHContentEditingOutput* output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input]; NSMutableData* adjustmentData = [NSMutableData data]; uint8_t byte = 1; [adjustmentData appendBytes:&byte length:1]; output.adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"com.yourcompany.yourapp" formatVersion:@"1.0f" data:adjustmentData];
Pandas 中 SettingwithCopyWarning 的原理和解决方案
原文链接:https://www.dataquest.io/blog/settingwithcopywarning/
原文标题:Understanding SettingwithCopyWarning in pandas
原文发布时间:5 JULY 2017(需要注意时效性,文中有一些方法已经弃用,比如 ix
)
作者:Benjamin Pryke
译者:Ivy Lee
学习 Python 数据分析的同学总是遇到这个警告,查询中文资料,一般只能找到个别的解决办法,不一定适用于自己遇到的情况。查到的最常见解决办法就是直接设置为不显示警告。搜索资料发现这篇英文讲解 SettingWithCopyWarning
原理非常系统的文章,翻译了一下,分享给大家。
SettingWithCopyWarning
是人们在学习 Pandas 时遇到的最常见的障碍之一。快速的网络搜索可以搜索到 Stack Overflow 问题,GitHub issues 和程序员的论坛帖子,试图解释这个警告在他们的特定情况下意味着什么。这么多人为此困扰并不奇怪:有很多方法可以索引 Pandas 数据结构,每种数据结构都有自己独特的细微差别,甚至 Pandas 本身并不能保证两行代码的运行结果看起来完全相同。
本指南解释了生成警告的原因并展示了如何解决这一警告。它还包括一些底层的细节,让你更好地了解代码内部发生了什么,提供了有关该话题的一些历史记录,让你了解为什么代码底层以这样的方式运作。
为了探索 SettingWithCopyWarning
,我们将使用 Modelling Online Auctions 一书中的 eBay 3 天拍卖出售的 Xbox 的价格数据集。让我们来看看:
import Pandas as pd
data = pd.read_csv(''xbox-3-day-auctions.csv'')
data.head()
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | |
---|---|---|---|---|---|---|---|
0 | 8213034705 | 95.0 | 2.927373 | jake7870 | 0 | 95.0 | 117.5 |
1 | 8213034705 | 115.0 | 2.943484 | davidbresler2 | 1 | 95.0 | 117.5 |
2 | 8213034705 | 100.0 | 2.951285 | gladimacowgirl | 58 | 95.0 | 117.5 |
3 | 8213034705 | 117.5 | 2.998947 | daysrus | 10 | 95.0 | 117.5 |
4 | 8213060420 | 2.0 | 0.065266 | donnie4814 | 5 | 1.0 | 120.0 |
如你所见,数据集的每一行都是某一次 eBay Xbox 出价信息。以下是该数据集中每列的简要说明:
auctionid
- 每次拍卖的唯一标识符bid
- 本次拍卖出价bidtime
- 拍卖的时长,以天为单位,从投标开始累计bidder
- 投标人的 eBay 用户名bidderrate
- 投标人的 eBay 用户评级openbid
- 卖方为拍卖设定的开标价price
- 拍卖结束时的中标价
什么是 SettingWithCopyWarning?
首先要理解的是,SettingWithCopyWarning
是一个警告,而不是错误 Error。
错误表明某些内容是 “坏掉” 的,例如无效语法(invalid syntax)或尝试引用未定义的变量。警告的作用是提醒程序员,他们的代码可能存在潜在的错误或问题,但是这些操作仍然是该编程语言中的合法操作。在这种情况下,警告很可能表明一个严重但不容易意识到的错误。
SettingWithCopyWarning
告诉你,你的操作可能没有按预期运行,你应该检查结果以确保没有出错。
如果你的代码仍然按预期工作,那么很容易忽略警告。这不是良好的实践,SettingWithCopyWarning
不应该被忽略。在采取下一步行动之前,花点时间了解为什么会获得这一警告。
要了解 SettingWithCopyWarning
,首先需要了解 Pandas 中的某些操作可以返回数据的视图(View),而某些其他操作将返回数据的副本(Copy)。
如上所示,左侧的视图 df2
只是原始 df1
一个子集,而右侧的副本创建了一个新的唯一对象 df2
。
当我们尝试对数据集进行更改时,这可能会导致问题:
根据我们的需求,我们可能想要修改原始 df1
(左),可能想要修改 df2
(右)。警告让我们知道,我们的代码可能并没有符合需求,修改的并不是我们想要修改的那个数据集。
我们稍后会深入研究这个问题,但是现在先来了解一下,警告出现的两个主要原因以及如何解决它们。
链式赋值(Chained assignment)
当 Pandas 检测链式赋值(Chained assignment)时会生成警告。让我们定义一些术语,方便后续的解释:
- 赋值(Assignment) - 设置某些变量值的操作,例如
data = pd.read_csv(''xbox-3-day-auctions.csv'')
。也被称为设置(set) 。 - 访问(Access) - 返回某些值的操作,例如下面的索引和链式索引示例。也被称为获取(get) 。
- 索引(Indexing) - 引用数据子集的任何赋值或访问方法,例如
data[1:5]
。 - 链式索引(Chaining) - 连续使用多个索引操作,例如
data[1:5][1:3]
。
链式赋值是链式索引和赋值的组合。先快速浏览一下之前加载的数据集,稍后我们将详细介绍这一点。在这个例子中,假设我们了解到用户 ''parakeet2004''
的 bidderrate 不正确,我们必须修改他的 bidderrate,首先,查看一下当前的值。
data[data.bidder == ''parakeet2004'']
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | |
---|---|---|---|---|---|---|---|
6 | 8213060420 | 3.00 | 0.186539 | parakeet2004 | 5 | 1.0 | 120.0 |
7 | 8213060420 | 10.00 | 0.186690 | parakeet2004 | 5 | 1.0 | 120.0 |
8 | 8213060420 | 24.99 | 0.187049 | parakeet2004 | 5 | 1.0 | 120.0 |
我们有三行要更新 bidderrate
字段,我们继续往下操作:
data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
/Library/Frameworks/Python.framework/Versions/36/lib/python3.6/ipykernel/__main__.py:1:SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from aDataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation:http://Pandas.pydata.org/Pandas-docs/stable/indexinghtml#indexing-view-versus-copy
if __name__ == ''__main__'':
不好了!我们神奇的造成了 SettingWithCopyWarning
!
如果检查一下,可以看到在这种情况下,值没有按预期改变:
data[data.bidder == ''parakeet2004'']
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | |
---|---|---|---|---|---|---|---|
6 | 8213060420 | 3.00 | 0.186539 | parakeet2004 | 5 | 1.0 | 120.0 |
7 | 8213060420 | 10.00 | 0.186690 | parakeet2004 | 5 | 1.0 | 120.0 |
8 | 8213060420 | 24.99 | 0.187049 | parakeet2004 | 5 | 1.0 | 120.0 |
生成警告是因为我们将两个索引操作链接在一起,我们直接使用了两次方括号,所以这比较容易理解。但如果我们使用其他访问方法,例如 .bidderrate
、.loc[]
、.iloc[]
、.ix[]
,也是如此,我们的链式操作是:
data[data.bidder == ''parakeet2004'']
[''bidderrate''] = 100
这两个链式操作一个接一个地独立执行。第一次是访问操作(get),返回一个 DataFrame
,其中包含所有 bidder
等于 ''parakeet2004''
的行。第二个是赋值操作(set),是在这个新的 DataFrame
上运行的,我们压根没有在原始 DataFrame
上运行。
这个解决方案很简单:使用 loc
将链式操作组合到一个操作中,以便 Pandas 可以确保 set 的是原始 DataFrame
。Pandas 会始终确保下面这样的非链式 set 操作起作用。
# 设置新值
data.loc[data.bidder == ''parakeet2004'', ''bidderrate''] = 100
# 检查结果 data[data.bidder == ''parakeet2004''][''bidderrate''] 6 100 7 100 8 100 Name: bidderrate, dtype: int64
这就是警告中建议我们做的操作,在这种情况下它完美地适用。
隐蔽的链式操作(Hidden chaining)
现在来看一下遇到 SettingWithCopyWarning
的第二种最常见的方式。我们来探索中标者的数据,我们将为此创建一个新的 DataFrame,现在已经学习了关于链式赋值的内容,因此请注意使用 loc
。
winners = data.loc[data.bid == data.price]
winners.head()
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | |
---|---|---|---|---|---|---|---|
3 | 8213034705 | 117.5 | 2.998947 | daysrus | 10 | 95.00 | 117.5 |
25 | 8213060420 | 120.0 | 2.999722 | djnoeproductions | 17 | 1.00 | 120.0 |
44 | 8213067838 | 132.5 | 2.996632 | * champaignbubbles* |
202 | 29.99 | 132.5 |
45 | 8213067838 | 132.5 | 2.997789 | * champaignbubbles* |
202 | 29.99 | 132.5 |
66 | 8213073509 | 114.5 | 2.999236 | rr6kids | 4 | 1.00 | 114.5 |
我们可能会使用 winners
变量编写一些后续的代码行。
mean_win_time = winners.bidtime.mean()
... # 20 lines of code
mode_open_bid = winners.openbid.mode()
偶然的机会,我们在该 DataFrame
发现了另一个错误:标记为 304
的行中缺少了 bidder
值。
winners.loc[304, ''bidder'']
nan
对这个例子来说,假设我们知道这个投标人的真实用户名,并以此更新数据:
winners.loc[304, ''bidder''] = ''therealname''
/Library/Frameworks/Python.framework/Versions/36/lib/python3.6/Pandas/core/indexing.py:517:SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from aDataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://Pandas.pydata.org/Pandas-docs/stable/indexing.html#indexing-view-versus-copy
self.obj[item] = s
另一个 SettingWithCopyWarning
!但我们使用了 loc
,这又是怎么回事?为了研究这一点,我们来看看代码的结果:
print(winners.loc[304, ''bidder''])
therealname
代码按预期工作了,为什么我们还是得到警告?
链式索引可能跨越两行代码发生,也可能在一行代码内发生。因为 winners
是作为 get 操作的输出创建的(data.loc[data.bid == data.price]
),它可能是原始 DataFrame
的副本,也可能不是,但除非我们检查,否则我们不能了解到。当我们对 winners
进行索引时,我们实际上使用的是链式索引。
这意味着当我们尝试修改 winners
时,我们可能也修改了 data
。
在实际的代码中,这些行可能会跨越很大的距离,因此追踪问题可能会更困难,但情况是与示例类似的。
为了防止这种情况下的警告,解决方案是在创建新 DataFrame 时明确告知 Pandas 制作一个副本:
winners = data.loc[data.bid == data.price].copy()
winners.loc[304, ''bidder''] = ''therealname''
print(winners.loc[304, ''bidder'']) print(data.loc[304, ''bidder'']) therealname nan
就这么简单!
窍门就是,学会识别链式索引,不惜一切代价避免使用链式索引。如果要更改原始数据,请使用单一赋值操作。如果你想要一个副本,请确保你强制让 Pandas 制作副本。这样可以节省时间,也可以使代码保持严密的逻辑。
另外请注意,即使 SettingWithCopyWarning
只在你进行 set 时才会发生,但在进行 get 操作时,最好也避免使用链式索引。链式操作较慢,而且只要你稍后决定进行赋值操作,就会导致问题。
处理 SettingWithCopyWarning 的提示和技巧
在我们进行下面更深入的分析之前,让我们 “拿出显微镜”,看看 SettingWithCopyWarning
的更多细节。
关闭警告
首先,如果不讨论如何明确地控制 SettingWithCopy
设置,那么本文则不完整。Pandas 的 mode.chained_assignment
选项可以采用以下几个值之一:
''raise''
- 抛出异常(exception)而不是警告''warn''
- 生成警告(默认)None
- 完全关闭警告
例如,如果要关闭警告:
pd.set_option(''mode.chained_assignment'', None)
data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
因为这样没有给我们任何警告,除非你完全了解自己在做什么,否则不建议这样做。如果你对想要实现的操作有任何一丁点的疑问,关闭警告都不被推荐。有些开发者非常重视 SettingWithCopy
甚至选择将其提升为异常,如下所示:
pd.set_option(''mode.chained_assignment'', ''raise'')
data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
---------------------------------------------------------------------------
SettingWithCopyError Traceback (most recent call last)
<ipython-input-13-80e3669cab86> in <module>()
1 pd.set_option(''mode.chained_assignment'', ''raise'')
----> 2 data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/Pandas/core/frame.py in __setitem__(self, key, value)
2427 else:
2428 # set column
-> 2429 self._set_item(key, value) 2430 2431 def _setitem_slice(self, key, value): /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/Pandas/core/frame.py in _set_item(self, key, value) 2500 # value exception to occur first 2501 if len(self): -> 2502 self._check_setitem_copy() 2503 2504 def insert(self, loc, column, value, allow_duplicates=False): /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/Pandas/core/generic.py in _check_setitem_copy(self, stacklevel, t, force) 1758 1759 if value == ''raise'': -> 1760 raise SettingWithCopyError(t) 1761 elif value == ''warn'': 1762 warnings.warn(t, SettingWithCopyWarning, stacklevel=stacklevel) SettingWithCopyError: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://Pandas.pydata.org/Pandas-docs/stable/indexing.html#indexing-view-versus-copy
如果你正在与缺乏经验的 Pandas 开发人员合作开发项目,或者正在开发需要高度严谨的项目,这可能特别有用。
使用此设置的更精确方法是使用 上下文管理器 context manager 。
# resets the option we set in the previous code segment
pd.reset_option(''mode.chained_assignment'')
with pd.option_context(''mode.chained_assignment'', None): data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
正如你所看到的,这种方法可以实现针对性的警告设置,而不是影响整个环境。
is_copy 属性
避免警告的另一个技巧是修改 Pandas 用于解释 SettingWithCopy
的工具之一。每个 DataFrame
都有一个 is_copy
属性,默认情况下为 None
,但如果它是副本,则会使用 weakref
引用原始 DataFrame
。通过将 is_copy
设置为 None
,可以避免生成警告。
winners = data.loc[data.bid == data.price]
winners.is_copy = None
winners.loc[304, ''bidder''] = ''therealname''
但是请注意,这并不会奇迹般地解决问题,反而会使错误检测变得非常困难。
单类型 VS 多类型对象
值得强调的另一点是单类型对象和多类型对象之间的差异。如果 DataFrame
所有列都具有相同的 dtype,则它是单类型的,例如:
import numpy as np
single_dtype_df = pd.DataFrame(np.random.rand(5,2), columns=list(''AB'')) print(single_dtype_df.dtypes) single_dtype_df A float64 B float64 dtype: object
A | B | |
---|---|---|
0 | 0.383197 | 0.895652 |
1 | 0.077943 | 0.905245 |
2 | 0.452151 | 0.677482 |
3 | 0.533288 | 0.768252 |
4 | 0.389799 | 0.674594 |
如果 DataFrame
的列不是全部具有相同的 dtype,那么它是多类型的,例如:
multiple_dtype_df = pd.DataFrame({''A'': np.random.rand(5),''B'': list(''abcde'')})
print(multiple_dtype_df.dtypes)
multiple_dtype_df
A float64
B object
dtype: object
A | B | |
---|---|---|
0 | 0.615487 | a |
1 | 0.946149 | b |
2 | 0.701231 | c |
3 | 0.756522 | d |
4 | 0.481719 | e |
由于下面历史部分中所述的原因,对多类型对象的索引 get 操作将始终返回副本。然而,为了提高效率,索引器对单类型对象的操作几乎总是返回一个视图,这里需要注意的是,这取决于对象的内存布局,并不能完全保证。
误报
误报,即无意中报告链式赋值的情况,曾经在早期版本的 Pandas 中比较常见,但此后大部分都被解决了。为了完整起见,在此处包括一些已修复的误报示例也是有用的。如果你在使用早期版本的 Pandas 时遇到以下任何情况,则可以安全地忽略或抑制警告(或通过升级完全避免警告!)
使用当前列的值,将新列添加到 DataFrame
会生成警告,但这已得到修复。
data[''bidtime_hours''] = data.bidtime.map(lambda x: x * 24)
data.head(2)
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | bidtime_hours | |
---|---|---|---|---|---|---|---|---|
0 | 8213034705 | 95.0 | 2.927373 | jake7870 | 0 | 95.0 | 117.5 | 70.256952 |
1 | 8213034705 | 115.0 | 2.943484 | davidbresler2 | 1 | 95.0 | 117.5 | 70.643616 |
当在一个 DataFrame
切片上使用 apply
方法进行设置时,也会出现误报,不过这也已得到修复。
data.loc[:, ''bidtime_hours''] = data.bidtime.apply(lambda x: x * 24)
data.head(2)
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | bidtime_hours | |
---|---|---|---|---|---|---|---|---|
0 | 8213034705 | 95.0 | 2.927373 | jake7870 | 0 | 95.0 | 117.5 | 70.256952 |
1 | 8213034705 | 115.0 | 2.943484 | davidbresler2 | 1 | 95.0 | 117.5 | 70.643616 |
最后,直到 0.17.0 版本前,DataFrame.sample
方法中存在一个错误,导致 SettingWithCopy
警告误报。现在,sample
方法每次都会返回一个副本。
sample = data.sample(2)
sample.loc[:, ''price''] = 120
sample.head()
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | bidtime_hours | |
---|---|---|---|---|---|---|---|---|
481 | 8215408023 | 91.01 | 2.990741 | sailer4eva | 1 | 0.99 | 120 | 71.777784 |
503 | 8215571039 | 100.00 | 1.965463 | lambonius1 | 0 | 50.00 | 120 | 47.171112 |
链式赋值深度解析
让我们重用之前的例子:试图更新 data
中 bidder
值为 ''parakeet2004''
的所有行的 bidderrate
字段。
data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ipykernel/__main__.py:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://Pandas.pydata.org/Pandas-docs/stable/indexing.html#indexing-view-versus-copy
if __name__ == ''__main__'':
Pandas 用这个 SettingWithCopyWarning
告诉我们的是,代码的行为是模棱两可的,但要理解为什么这样做以及警告的措辞,以下概念将会有所帮助。
我们之前简要地谈过了视图(View)和副本(Copy)。有两种方法可以访问 DataFrame
的子集:可以创建对内存中原始数据的引用(视图),也可以将子集复制到新的较小的 DataFrame
中(副本)。视图是查看 原始 数据特定部分的一种方式,而副本是将该数据克隆到内存中的新位置。正如我们之前的图表所示,修改视图将修改原始变量,但修改副本则不会。
由于某些我们将在稍后介绍的原因,Pandas 中 get 操作的输出无法保证。索引 Pandas 数据结构时,视图或副本都可能被返回,这意味着对某一 DataFrame
进行 get 操作返回一个新的 DataFrame
,这个新的数据可能是:
- 来自原始对象的数据副本。
- 没有复制,而是直接对原始对象的引用。
因为我们不知道将会发生什么,并且每种可能性都有非常不同的行为,所以忽略警告就是 “玩火”。
为了更清楚地解释视图、副本和其中的歧义,让我们创建一个简单的 DataFrame
并对其进行索引:
df1 = pd.DataFrame(np.arange(6).reshape((3,2)), columns=list(''AB''))
df1
A | B | |
---|---|---|
0 | 0 | 1 |
1 | 2 | 3 |
2 | 4 | 5 |
将 df1
的子集赋值给 df2
:
df2 = df1.loc[:1]
df2
A | B | |
---|---|---|
0 | 0 | 1 |
1 | 2 | 3 |
根据刚才学到的知识,我们知道 df2
可能是 df1
的视图或 df1
子集的副本。
在解决问题之前,我们还需要再看一下链式索引。扩展一下 ''parakeet2004''
示例,我们将两个索引操作链接在一起:
data[data.bidder == ''parakeet2004'']
__intermediate__[''bidderrate''] = 100
__intermediate__
表示第一个调用的输出,对我们是完全不可见的。请记住,如果我们使用了属性访问,会得到相同的有问题的结果:
data[data.bidder == ''parakeet2004''].bidderrate = 100
这同样适用于任何其他形式的链式调用,因为我们正在生成中间对象 。
在底层代码中,链式索引意味着对 __getitem__
或 __setitem__
进行多次调用以完成单个操作。这些是 特殊的 Python 方法,通过在实现它们的类的实例上使用方括号,可以调用这些方法,这是语法糖的一种示例。让我们看一下 Python 解释器如何执行我们示例中的内容。
# Our code
data[data.bidder == ''parakeet2004''][''bidderrate''] = 100
# Code executed data.__getitem__(data.__getitem__(''bidder'') == ''parakeet2004'').__setitem__(''bidderrate'', 100)
正如你可能已经意识到的那样,SettingWithCopyWarning
是由此链式 __setitem__
调用生成的。你可以自己尝试一下 - 上面这些代码的功能相同。为清楚起见,请注意第二个 __getitem__
调用(对 bidder
列)是嵌套的,而不是链式问题的所有部分。
通常,如上面所述,Pandas 不保证 get 操作是返回视图还是副本。如果在我们的示例中返回了一个视图,则链式赋值中的第二个表达式将是对原始对象 __setitem__
的调用。但是,如果返回一个副本,那么将被修改的是副本 - 原始对象不会被修改。
这就是警告中 “a value is trying to be set on a copy of a slice from a DataFrame” 的含义。由于没有对此副本的引用,它最终将被回收 。SettingWithCopyWarning
让我们知道 Pandas 无法确定第一个 __getitem__
调用是否返回了视图或副本,因此不清楚该赋值是否更改了原始对象。换一种说法就是:“我们是否正在修改原始数据?” 这一问题的答案是未知的。
如果我们确实想要修改原始文件,警告建议的解决方案是使用 loc
将这两个单独的链式操作转换为单个赋值操作。这样我们的代码中没有了链式索引,就不会再收到警告。我们修改后的代码及其扩展版本如下所示:
# Our code
data.loc[data.bidder == ''parakeet2004'', ''bidderrate''] = 100
# Code executed data.loc.__setitem__((data.__getitem__(''bidder'') == ''parakeet2004'', ''bidderrate''), 100)
DataFrame 的 loc
属性保证是原始 DataFrame
本身,具有扩展的索引功能。
假阴性(False negatives)
使用 loc
并没有结束我们的问题,因为使用 loc
的 get 操作仍然可以返回一个视图或副本。让我们快速过一下,一个有点复杂的例子。
data.loc[data.bidder == ''parakeet2004'', (''bidderrate'', ''bid'')]
bidderrate | bid | |
---|---|---|
6 | 100 | 3.00 |
7 | 100 | 10.00 |
8 | 100 | 24.99 |
我们这次拉出了两列而不是一列。让我们尝试 set 所有的 bid
值。
data.loc[data.bidder == ''parakeet2004'', (''bidderrate'', ''bid'')][''bid''] = 5.0 data.loc[data.bidder == ''parakeet2004'', (''bidderrate'', ''bid'')]
bidderrate | bid | |
---|---|---|
6 | 100 | 3.00 |
7 | 100 | 10.00 |
8 | 100 | 24.99 |
没有效果,也没有警告!我们在切片的副本上 set 了一个值但是 Pandas 没有检测到它 - 这就是假阴性。这是因为,使用 loc
之后并不意味着我们可以再次使用链式赋值。这个特定的 bug,有一个未解决的 GitHub issue 。
正确的解决方法如下:
data.loc[data.bidder == ''parakeet2004'', ''bid''] = 5.0
data.loc[data.bidder == ''parakeet2004'', (''bidderrate'', ''bid'')]
bidderrate | bid | |
---|---|---|
6 | 100 | 5 |
7 | 100 | 5 |
8 | 100 | 5 |
你可能怀疑,是否有人会在实践中遇到这样的问题。其实这比你想象的更容易出现。当我们像下一节中这样做:将 DataFrame
查询的结果赋值给变量。
隐藏的链式索引
让我们再看一下之前隐藏的链式索引示例,我们试图设置 winners
变量中,标记为 304
行的 bidder
字段。
winners = data.loc[data.bid == data.price]
winners.loc[304, ''bidder''] = ''therealname''
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/Pandas/core/indexing.py:517: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://Pandas.pydata.org/Pandas-docs/stable/indexing.html#indexing-view-versus-copy
self.obj[item] = s
我们得到了另一个 SettingWithCopyWarning
尽管我们使用了 loc
。这个问题可能令人非常困惑,因为警告信息建议我们的方法,我们已经做过了。
不过,想一下 winners
变量。它究竟是什么?由于我们通过 data.loc[data.bid == data.price]
将它初始化,我们无法知道它是原始 data
DataFrame
的视图还是副本(因为 get 操作返回视图或副本)。将初始化与生成警告的行组合在一起可以清楚地表明我们的错误。
data.loc[data.bid == data.price].loc[304, ''bidder''] = ''therealname''
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/Pandas/core/indexing.py:517: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://Pandas.pydata.org/Pandas-docs/stable/indexing.html#indexing-view-versus-copy
self.obj[item] = s
我们再次使用了链式赋值,只是这次它被分在了两行代码中。思考这个问题的另一种方法是,问一个问题 “这个操作会修改一个对象,还是两个对象?” 在我们的示例中,答案是未知的:如果 winners
是副本,那么只有 winners
受到影响,但如果是视图,则 winners
和 data
都将被更新。这种情况可能发生在脚本或代码库中相距很远的行之间,这使问题很难被追根溯源。
此处警告的意图是让我们意识到,我们以为代码将修改原始 DataFrame
,实际没有修改成功,或者说我们将修改副本而不是原始数据。深入研究 Pandas GitHub repo 中的 issue,你可以看到开发人员自己对这个问题的解释。
如何解决这个问题在很大程度上取决于我们自己的意图。如果我们想要使用原始数据的副本,解决方案就是强制 Pandas 制作副本。
winners = data.loc[data.bid == data.price].copy()
winners.loc[304, ''bidder''] = ''therealname''
print(data.loc[304, ''bidder'']) # Original print(winners.loc[304, ''bidder'']) # Copy nan therealname
另一方面,如果你需要更新原始 DataFrame
,那么你应该使用原始 DataFrame
而不是重新赋值一些具有未知行为的其他变量。我们之前的代码将修改为:
# Finding the winners
winner_mask = data.bid == data.price
# Taking a peek
data.loc[winner_mask].head()
# Doing analysis
mean_win_time = data.loc[winner_mask, ''bidtime''].mean()
... # 20 lines of code mode_open_bid = data.loc[winner_mask, ''openbid''].mode() # Updating the username data.loc[304, ''bidder''] = ''therealname''
在更复杂的情况下,例如修改 DataFrame
子集的子集,不要使用链式索引,可以在原始 DataFrame
上通过 loc
进行修改。例如,你可以更改上面的新 winner_mask
变量或创建一个选择中标者子集的新变量,如下所示:
high_winner_mask = winner_mask & (data.price > 150)
data.loc[high_winner_mask].head()
auctionid | bid | bidtime | bidder | bidderrate | openbid | price | bidtime_hours | |
---|---|---|---|---|---|---|---|---|
225 | 8213387444 | 152.0 | 2.919757 | uconnbabydoll1975 | 15 | 0.99 | 152.0 | 70.074168 |
328 | 8213935134 | 207.5 | 2.983542 | toby2492 | 0 | 0.10 | 207.5 | 71.605008 |
416 | 8214430396 | 199.0 | 2.990463 | volpendesta | 4 | 9.99 | 199.0 | 71.771112 |
531 | 8215582227 | 152.5 | 2.999664 | ultimatum_man | 2 | 60.00 | 152.5 | 71.991936 |
这种技术会使得未来的代码库维护和扩展更加稳健。
历史
你可能想知道为什么要造成这么混乱的现状,为什么不明确指定索引方法是返回视图还是副本,来完全避免 SettingWithCopy
问题。要理解这一点,我们必须研究 Pandas 的过去。
Pandas 确定返回一个视图还是一个副本的逻辑,源于它对 NumPy 库的使用,这是 Pandas 库的基础。视图实际上是通过 NumPy 进入 Pandas 的词库的。实际上,视图在 NumPy 中很有用,因为它们能够可预测地返回。由于 NumPy 数组是单一类型的,因此 Pandas 尝试使用最合适的 dtype 来最小化内存处理需求。因此,包含单个 dtype 的 DataFrame
切片可以作为单个 NumPy 数组的视图返回,这是一种高效处理方法。但是,多类型的切片不能以相同的方式存储在 NumPy 中。Pandas 兼顾多种索引功能,并且保持高效地使用其 NumPy 内核的能力。
最终,Pandas 中的索引被设计为有用且通用的方式,其核心并不完全与底层 NumPy 数组的功能相结合。随着时间的推移,这些设计和功能元素之间的相互作用,导致了一组复杂的规则,这些规则决定了返回视图还是副本。经验丰富的 Pandas 开发者通常都很满意 Pandas 的做法,因为他们可以轻松地浏览其索引行为。
不幸的是,对于 Pandas 的新手来说,链式索引几乎是不可避免的,因为 get 操作返回的就是可索引的 Pandas 对象。此外,用 Pandas 的核心开发人员之一 Jeff Reback 的话来说,“从语言的角度来看,直接检测链式索引是不可能的,必须经过推断才能了解”。
因此,在 2013 年底的 0.13.0 版本中引入了警告,作为许多开发者遇到链式赋值导致的无声失败的解决方案。
在 0.12 版本之前,ix
索引器是最受欢迎的(在 Pandas 术语中,“索引器” 比如 ix
,loc
和 iloc
,是一种简单的结构,允许使用方括号来索引对象,就像数组一样,但具有一些特殊的用法)。但是大约在 2013 年中 ,Pandas 项目开始意识到日益增加的新手用户的重要性,有动力开始提高新手用户的使用体验。自从此版本发布以来,loc
和 iloc
索引器因其更明确的性质和更易于解释的用法而受到青睐。(译者注:pandas v0.23.3 (July 7, 2018),其中 ix
方法已经被弃用)
SettingWithCopyWarning
在推出后持续改进,多年来在许多 GitHub issue 中得到了热烈的讨论 ,甚至还在不断更新 ,但是要理解它,仍然是成为 Pandas 专家的关键。
总结
SettingWithCopyWarning
的基础复杂性是 Pandas 库中为数不多的坑。这个警告的源头深深嵌在库的底层中,不应被忽视。Jeff Reback 自己的话 ,“我没有找到任何你应该忽略这个警告的情况。如果你做某些类型的索引时不起作用,而其他情况下起作用,你是在玩火。”
幸运的是,解决警告只需要识别链式赋值并修复。如果整篇文章你只了解到了一件事,那么就应该是这一点。
作者:笨熊不紧张
链接:https://www.jianshu.com/p/72274ccb647a
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
关于熊猫:SettingWithCopyWarning和熊猫计划的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Beginners Guide to Getting Started with AS3 (Without Learning Flex)、Fixing "perl: warning: Setting locale failed."、iOS照片扩展finishContentEditingWithCompletionHandler:无法保存更改、Pandas 中 SettingwithCopyWarning 的原理和解决方案等相关知识的信息别忘了在本站进行查找喔。
本文标签: