The story of Python and the story of NaN

Kinki University Advent Calendar 2019 Day 10 I was very surprised that the Advent calendar, which I started with a light feeling, was filled all day. I am very grateful to everyone who participated, thank you.

In this article, I'll show you what I've done with Python. Also, I will leave what I investigated when I was addicted to NaN. I would like to look back on myself and become a teacher on the other hand.

== and is

After getting used to Python, while trying to write Pythonic, an acquaintance said, "In Python, it is more fashionable to judge equivalence with ʻis!", And I have replaced all == with ʻis. .. Then it seems to work right, but ...

== Difference in behavior between is and is == determines if the values are equal is determines if the object ids are equal

Even if the Python strings and lists have the same value, the object id may be different. (If Japanese is entered in the character string, I feel that it will be strange in ʻis), so if you judge with ʻis, False will be returned even if the value is the same, and you will be addicted to it.

left = "python"
# ==Judgment
left == "python"
# > True
#is judgment
left is "python"
# > False

Reference copy of a two-dimensional array

Python can multiply strings and arrays with *.

"Ora" * 10
# 'Ora Ora Ora Ora Ora Ora Ora Ora Ora'
[0] * 10
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

However, if you generate it as a two-dimensional array with this, you will fall into the trap of reference copy. I didn't notice this and it melted for a long time ... I think it's better to write in list comprehension, etc. without wearing it sideways.

two_d_list = [[0] * 10] * 10
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

# [0,0]I want to add only the value of
two_d_list[0][0] += 1
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

for statement

Unlike Python's C etc., the for statement is a mechanism that iterates over sequence types. So, I'm addicted to doing the following.

  1. Even if the target list such as ʻi` is changed in the middle, it is not reflected.
  2. Append to a sequence object in a loop from the inside, resulting in an infinite loop

I think I have to give up on the first one ... The second can be solved by using slice notation

num_list = list(range(1, 4))
#There is no point in playing with the target list in the middle
for i in num_list:
  i += 1
# 1
# 2
# 3

#Append in a loop using slices
for i in num_list[:]:
# [1, 2, 3, 1, 2, 3]

Python interpreter

If you have a little math or something you want to try, you often call a Python interprinter from your terminal. However, once you press enter, you cannot go back and often say, "Oh, I made a mistake in the variable name" or "Oh, I made a mistake in indentation." So I started using ʻipython`. ipython is recommended because it is superior to the default interprinter as an interactive environment where you can execute commands in an environment where you execute code in cells that you are familiar with in jupyter notebook.

Module of gcd function version 3.4 or lower

This is mainly related to AtCoder, but if the Python version is 3.4 or lower, the gcd function is not in the math module (the current Python3 version of AtCoder is 3.4).

The gcd function is placed in the math module since 3.5, and earlier versions have it in the fractions module and must be used. It may be a trivial matter, but it was quite a bit of a challenge for a competitive professional who missed a minute and a second.

# 3.This cannot be used for 4 or less
from math import gcd
# 3.Use this before 4(3.Not recommended after 5)
from fractions import gcd


a bit pattern of a single-precision or double-precision real number data type that is a result of an invalid floating point operation. Translation: Bit patterns of single-precision or double-precision real data types that are the result of invalid floating-point operations From IEEE 754

I've always thought that the function that determines NaN in Pandas is df.isnan () (?) It's actually df.isnull (). math.isnan () and numpy.isnan () are also valid for individual determination.

Bonus (rather the main subject)

np.nan == np.nan # is always False! Use special numpy functions instead.

NaN has a characteristic that it returns False in numerical comparison and equivalent operation with everything (it is also from this characteristic that it returns False in comparison with itself), but is compared by reference is not a numerical comparison. , This principle does not apply. However, Python has two types of NaN, math.nan and numpy.nan, which have different object ids.

#Comparison between NaNs using is
math.nan is math.nan
# True

#math module NaN
# 4538852576
#NaN in the numpy library
# 4569389960

However, these are able to correctly determine each NaN with a function in a separate library.

#Each isnan()NaN can be judged correctly by the function
math.isnan(np.nan) and np.isnan(math.nan)
# True

I was curious about what kind of implementation it was, so I checked it.

Implementation of math.isnan

The implementation of math.nan seems to follow the implementation of C from cpython. I referred to this site for the implementation of C.

#define Py_IS_NAN(X) isnan(X)

Implementation of numpy.nan

From NumPy core libraries you can see that it follows the C99 implementation.

.. c:function:: int npy_isnan(x) This is a macro, and is equivalent to C99 isnan: works for single, double and extended precision, and return a non 0 value is x is a NaN.

In other words, the object id is different, but the original implementation is the same in C, so it works the same. Somehow I was expecting it, but I'm glad if I can actually confirm it!

in conclusion

I've reached the limit of the ad-care deadline, but iCould is bad because it also hindered backups and took 3 days to back up about 25G.

Recommended Posts

The story of Python and the story of NaN
The story of Python without increment and decrement operators.
The story of making Python an exe
The story of manipulating python global variables
The story of trying deep3d and losing
The story of blackjack A processing (python)
the zen of Python
The story of sys.path.append ()
The story of running python and displaying the results without closing vim
The story of low learning costs for Python
Summary of the differences between PHP and Python
The answer of "1/2" is different between python2 and 3
Specifying the range of ruby and python arrays
Compare the speed of Python append and map
Image processing? The story of starting Python for
The story of reading HSPICE data in Python
About the * (asterisk) argument of python (and itertools.starmap)
A discussion of the strengths and weaknesses of Python
The story of building Zabbix 4.4
Towards the retirement of Python2
[Apache] The story of prefork
About the ease of Python
About the features of Python
Source installation and installation of Python
The Power of Pandas: Python
The process of installing Atom and getting Python running
Python --Explanation and usage summary of the top 24 packages
Visualize the range of interpolation and extrapolation with python
The story of FileNotFound in Python open () mode ='w'
Referencing and changing the upper bound of Python recursion
I checked out the versions of Blender and Python
The story of automatic language conversion of TypeScript / JavaScript / Python
Environment construction of python and opencv
The story of implementing the popular Facebook Messenger Bot with python
Installation of SciPy and matplotlib (Python)
[Python] The stumbling block of import
[Python] Heron's formula functionalization and calculation of the maximum area
First Python 3 ~ The beginning of repetition ~
The story of how the Python bottle worked on Sakura Internet
The story of participating in AtCoder
The story of introducing jedi (python auto-completion package) to emacs
Existence from the viewpoint of Python
pyenv-change the python version of virtualenv
NaN story
[python] plot the values ​​before and after the conversion of yeojohnson conversion
Change the Python version of Homebrew
This and that of python properties
The story of rubyist struggling with python :: Dict data with pycall
The story of the "hole" in the file
[Python] Understanding the potential_field_planning of Python Robotics
Review of the basics of Python (FizzBuzz)
The process of making Python code object-oriented and improving it
The websocket of toio (nodejs) and python / websocket do not connect.
I want to know the features of Python and pip
[Tips] Problems and solutions in the development of python + kivy
[Python] Tensorflow 2.0 did not support Python 3.8, so the story of downgrading Python
Coexistence of Python2 and 3 with CircleCI (1.0)
The story of remounting the application server
Strange and horrifying Python error story
About the basics list of Python basics
Story of power approximation by Python