未分類」カテゴリーアーカイブ

DataFrameの特定の列の値に基づいて行を並べ替える方法 KeyError:の解決

DataFrameの特定の列の値に基づいて行を並べ替えたいと思ったのですがKeyError:が出て苦労したので、解決したいきさつをメモしておきます。自分の扱ったデータは、カラム(列)が年度、行が人名で、データは数字です。個人個人のとある数値データの年推移をまとめたものです。

解決のきっかけは、このサイトの記事。

  1. 【Pythonエラー】Pandas Dataframeカラム名指定でKey Error→カラム名確認して原因特定 Qiita @kath_y 2019年07月25日

カラム名に、目に見えない(表示されない)空白文字があったからというものでした。print(df.columns) でカラム名の確認からやっていました。この人の結果は、

Index([‘sepal length (cm)’, ‘sepal width (cm)’, ‘petal length (cm)’, ‘petal width (cm)’], dtype=’object’)

自分も試してみたところ、

Int64Index([2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020], dtype=’int64′, name=’Year’)

となりました。ちなみに、目でみたところはカラム名は、’2011′, ‘2012’, のように文字列だと思っていました。なので、

df.sort_values(by=[‘2012’])

で良いのだろうと思ったのですが、

KeyError: ‘2012’

となって途方に暮れていました。上のチェックでわかったことは、カラム名が文字列としての数字ではなく、本当に数字、つまりインテジャー(整数)だったということ。ならばと思って、

df.sort_values(by=[2012],ascending=False)

と数字をそのまま放りこんだらうまく期待した動作をしてくれました。ascending=False 昇順じゃないよということで降順にする指定方法。2012という名前のカラム(列)の値が降順になるように、行を入れ替えるという動作になります。

文字列を要素とするリストにおいて、空の要素を除く方法 リスト内包表記をマスター

文書の処理をpythonでやっているときに、文字を何も含まない要素がリストの中に紛れ込むことがありました。それを除く方法を調べてみました。

何も含まない要素を含むリストを作って試します。

mylist = [”,’a’,”]
print(mylist)

mylist = [i for i in mylist if i != ”]
print(mylist)

結果は

['', 'a', '']
['a']

となり、うまく除去できています。このfor文の使い方は、知らないと絶対に思いつかないと思いますが、慣れればとても便利な方法です。条件の内容を変えることにより、応用範囲が広がります。

[iに関する式 for i in リスト] という構造になっていて、リストの各要素に関してiに関する式であらわされる新しい要素からなるリストを作っています。これはリスト内包表記と呼ばれるみたいです。

リスト内の要素に関して条件を付けたければ、

[iに関する式 for i in リスト if 条件]

という書式になります。このやり方を覚えておくと、リスト内の要素の抽出や加工の際にとても便利。

jupyterノートブックでコードの全てをコメントアウトする方法?

疑問:jupyterノートブックでコードの全てをコメントアウトする方法?(ウインドウズ10で利用時)

回答:コメントアウトしたい部分を選択しておき、Ctlキーと/キーを同時に押す。ちなみに、同じ操作をもう一度やると、今度はコメントを除くことができる。

.str.containsを使おうとするとValueError: cannot index with vector containing NA / NaN valuesのエラーになる件【解決】

df[‘データフレームの列の名前’].str.contains(“調べたいキーワード”)という構文を使おうとしたら、

ValueError: cannot index with vector containing NA / NaN values

というエラーを食らいました。解決法は簡単で、

na=False

という指定を足してやればよかっただけでした。

df[‘データフレームの列の名前’].str.contains(“調べたいキーワード”, na=False)

で事足りました。ちなみにもしna=Trueと指定すると、NaNの行は、Trueつまり、”調べたいキーワードがあったこと”として扱われるようです。

 

参考にしたサイト

  1. pandas データフレームをstr.contains()で処理し、nan値を無視したい (2018/01/11 15:41 teratail.com 質問をすることでしか得られない、回答やアドバイスがある。)
  2. pandasで特定の文字列を含む行を抽出(完全一致、部分一致)https://note.nkmk.me/

リスト内包表記で複数の条件を用いるときの書式

リスト内包表記は非常に便利で、様々な条件に適合する要素だけをリストから抽出することができます。一つの条件だけでなく、複合条件を適用することもできるようです。

所属リスト = [‘東京大学医学部’, ‘京都大学医学部’, ‘東京大学理学部’, ‘東京大学’, ‘東京大学病院’]
東大医 = [s for s in 所属リスト if (‘東京大学’ in s) and ((‘医学部’ in s) or (‘病院’ in s)) ]
print(東大医)

 

出力結果は、

 

[‘東京大学医学部’, ‘東京大学病院’]

 

となりました。

 

参考

  1. Pythonで文字列のリスト(配列)の条件を満たす要素を抽出、置換(nkmk)

python pandas データフレームをゼロから作る方法 初期値として全てに0をセット

データフレームの作り方はいろいろあります。既存のエクセルファイルを読み込んだり、リストの形になっているデータを読み込んだり。しかし、データがあとから生成される場合に、最初に「空」のデータフレームを作っておきたい場合もあります。行名、列名は指定して、値は全て0を初期値とするデータフレームの作り方。

 

import pandas as pd

 

行名 = [2016,2017,2018,2019,2020]
列名 = [‘Medicine’,’Science’]
df = pd.DataFrame(index=行名, columns=列名)

for col in df.columns:

df[col].values[:] = 0

python3では日本語も変数名として使えるので、上のコードではそうしてみました。

 

dfの出力結果は、

Medicine Science
2016 0 0
2017 0 0
2018 0 0
2019 0 0
2020 0 0

となります。

【対処法・解決】エラーメッセージ UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0x8c in position 62517: invalid start byte

タブ区切りのCSVファイルをpandasのread_table()メソッドを用いてデータフレームとして読み込もうとしたときに、

df = pd.read_table(file)

UnicodeDecodeError: ‘utf-8′ codec can’t decode byte 0x8c in position 62517: invalid start byte というエラーが出てしまい、にっちもさっちもいかなくなって困りました。ネットで見かけた解決策をあれこれ試しても全然効果なし。ところが、encoding=’unicode_escape’を付けてみたら、

 

df = pd.read_table(file, encoding=’unicode_escape’)

 

無事読み込めました。

pythonの辞書(dictionary)の配列を作成する方法

pythonのモジュールpandasの中にあるDataFrameはエクセルなどの表の処理に便利ですが、各々のカラムの長さ(要素の数)が同じでないといけないという制約があるようです。そのため、要素の数などに制限がないようにと、辞書(dictionary)の配列を作ることを考えましたが、やり方がわからずネットで検索した結果、やり方が紹介されているのを見つけました。

  1. How can I create an array/list of dictionaries in python? (stackoverflow)
dictlist = [dict() for x in range(10)]

と簡単に10個の辞書からなる配列が作れました。