ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

2016年11月21日月曜日

PandasでSeriesオブジェクトとDataFrameオブジェクトを作る

Pandasのデータ構造


Pandasでは、データの入出力、抽出、並べ替えなどの処理をすることができる。
Pandasでは、主に以下の2つのデータ構造が定義されている。
- Series:ラベル付きの1次元配列
- DataFrame:ラベル付きの2次元配列。スプレッドシートやデータベースのテーブルや辞書のようなもの。

pandas.Series()


まず、Seriesオブジェクトを作ってみる

import pandas as  pd

s = pd.Series([10 , 4, 7, 34, 6])
s

#結果
#0    10
#1     4
#2     7
#3    34
#4     6
#dtype: int64

date_range()を使って日付をインデックスにすることもできる。

import pandas as  pd

s = pd.Series([10 , 4, 7, 34, 6], index=date_range('1/1/2016', periods=5))
s

#結果
#2016-01-01    10
#2016-01-02     4
#2016-01-03     7
#2016-01-04    34
#2016-01-05     6
#Freq: D, dtype: int64

pandas.DataFrame()


次に、DataFrameオブジェクトを作ってみる。
適当に果物屋さんの売上のようなものでやってみましょうか。

import pandas as  pd

fruit_sales = {'Fruits': ['Apple', 'Orange', 'Grape', 'Peach', 'Lemon'],
                'Price': [100, 120, 150, 130, 90],
                'Sold': [14, 40, 23, 25, 12]}

df = pd.DataFrame(fruit_sales)
df

#結果
#   Fruits  Price  Sold
#0   Apple    100    14
#1  Orange    120    40
#2   Grape    150    23
#3   Peach    130    25
#4   Lemon     90    12

もちろん、インデックスを指定することもできる。
set_index()を使って、Fruitsをインデックスにしてみましょう。

import pandas as  pd

fruit_sales = {'Fruits': ['Apple', 'Orange', 'Grape', 'Peach', 'Lemon'],
                'Price': [100, 120, 150, 130, 90],
                'Sold': [14, 40, 23, 25, 12]}

df = pd.DataFrame(fruit_sales)
df.set_index('Fruits', inplace=True)
df

#結果
#        Price  Sold
#Fruits             
#Apple     100    14
#Orange    120    40
#Grape     150    23
#Peach     130    25
#Lemon      90    12

指定したカラムだけを抽出することもできる。

df = pd.DataFrame(fruit_sales)
df['Price']
#df.Price ←このようにドットでつなげても同じ結果が得られる

#結果
#0    100
#1    120
#2    150
#3    130
#4     90
#Name: Price, dtype: int64

複数のカラムを抽出することもできる。

df = pd.DataFrame(fruit_sales)
df[['Price', 'Sold']]

#結果
#   Price  Sold
#0    100    14
#1    120    40
#2    150    23
#3    130    25
#4     90    12

1次元配列(Series)であれば、tolist()を使って、指定したカラムの値をリストにすることが可能。

df = pd.DataFrame(fruit_sales)
df.Price.tolist()

#結果
#[100, 120, 150, 130, 90]

しかし、以下のように2次元配列(DataFrame)にはtolist()を使うことはできない。
DataFrameオブジェクトにはtolistという属性はないと怒られます。

df = pd.DataFrame(fruit_sales)
print(df[['Price', 'Sold']].tolist())

AttributeError: 'DataFrame' object has no attribute 'tolist'

こういった多次元のデータセットを扱うにはNumpyを使うのがいい。Numpyをインポートして、np.array()でN次元配列を扱うことができる。

import numpy as np

df = pd.DataFrame(fruit_sales)
print(np.array(df[['Price', 'Sold']]))

#結果
#[[100  14]
 #[120  40]
 #[150  23]
 #[130  25]
 #[ 90  12]]

2016年10月28日金曜日

pythonでリストの各要素の四則演算をする

以下のリスト内にある全ての要素を掛け算する(足し算でも引き算でもいい)方法をメモります。
言語はpython3です。

nums = [1, 2, 3, 4, 5]

使うモジュール


実行結果


では、実際にnumsの積を求めてみる。
operatorモジュールからmul関数をインポートする。
functoolsモジュールからreduce関数をインポートする。
reduce関数は関数とイテラブルを引数にとって、イテラブルの要素に対して、左から右に累積的に関数を適用する。

from operator import mul
from functools import reduce

nums = [1,2,3,4,5]
print(reduce(mul, nums)) #結果=>120

関数を作ってみる


次に、任意の数だけ引数を与えて、その積を返してくれる関数を作ってみます。

from operator import mul
from functools import reduce

def mul_nums(*args):
nums = []
for i in args:
    nums.append(i)
return reduce(mul, nums)

mul_num(1,2,3,4,5)  #結果=>120

もちろん足し算、引き算、割り算もできる。

足し算

from operator import add
from functools import reduce

def add_nums(*args):
nums = []
for i in args:
    nums.append(i)
return reduce(add, nums)

add_num(1,2,3,4,5)  #結果=>15

引き算

from operator import sub
from functools import reduce

def sub_nums(*args):
nums = []
for i in args:
    nums.append(i)
return reduce(sub, nums)

sub_num(1,2,3,4,5)  #結果=>-13

割り算

from operator import truediv
from functools import reduce

def div_nums(*args):
nums = []
for i in args:
    nums.append(i)
return reduce(truediv, nums)

div_num(1,2,3,4,5)  #結果=>0.008333333333333333

無名関数

ちなみにlambdaを使うと一行でいける。

from operator import add, mul, sub,truediv, floordiv
from functools import reduce

reduce(lambda x, y: x*y, [1, 2, 3, 4, 5])   #結果=>120

2016年8月29日月曜日

BeautifulSoupではまったこと

はまったこと


“http://hoge.com/” というサイトから、以下のHTMLのhrefとimg srcの絶対パスを抽出したかった。

<article>
    <figure><a href="/hogehoge?id=abcde"><img src="http://hoge.com/1/hoge.jpg"></figure>
</article>

しかし、a hrefは相対パスで記載されているので、普通にスクレイピングすると相対パスしか抽出できない。
img srcの方はうまく抽出できず、以下のようになってしまった。

[<img src="http://hoge.com/1/hoge.jpg">]    

使ったもの


  • Python3
  • Beautifulsoup4.5.1

BeautifulSoupをインストール


BeautifulSoup4はpipでインストール

pip install beautifulsoup4    

実行サンプル


urllib.requestモジュール、urllib.parseモジュールのurljoinメソッド、BeautifulSoupをインポートする。

import urllib.request
from urllib.parse import urljoin
from bs4 import BeautifulSoup

hrefの絶対パスを取得するときにurljoinを使うので、該当HPのurlを変数に入れておく。

url = "http://hoge.com/"

urllib.requestモジュールのurlopenメソッドでurlを開く。
BeautifulSoupを使ってスクレイピングするときに使いたいので、インスタンスを作成。

html = urllib.request.urlopen(url)

BeautifulSoupのインスタンスを作成。

soup = BeautifulSoup(html, "lxml")

HTMLからarticleタグを取得

for item in soup.find_all("article"): 

hrefの絶対パスはurlとhrefの相対パスをurljoinでつなげて作成する

    link = urljoin(url, item.a.get("href"))

img srcの絶対パスは以下のようにすれば取得できる。
絶対パスはimg_path。

    img = item.find("img")
    img_path = img["src"]