| Yang |


  • Home

  • Tags

  • Archives

浅草キッド

Posted on 2019-01-30

back

早已忘了是什么时候知道北野武这个名字的,只是知道他很屌,后来看了《菊次郎的夏天》《战场上的圣诞快乐》等电影才稍微有了多一点的了解。

记得《战场上的圣诞快乐》的结局里,随着坂本龙一的mcml渐渐响起,屏幕上是北野武那张大脸,他用英文说出“Merry Christmas,Lawrence.”,眼角有点湿润…

北野武

前段时间听到这一首《浅草キッド》,被打中了啊

浅草キッド-网易云
浅草キッド-Bilibili

歌词

お前と会った 仲見世の
与你相见在仲见世
煮込みしかない 鯨屋で
那间只有煮菜的鲸肉店
夢を語ったチュー八イの
我们谈论梦想
泡にはじけた 約束は
汽酒泡沫里消失的约定
灯的消元た 浅草の
在灯火暗去的浅草
コ夕ツ1つの アパートで
只有一个被炉的公寓

同じ背広を初めて買って
第一次买了同样的西装
同じ形の ちょうたい作り
做了同样的蝴蝶结领带
同じ靴まで 買う金はなく
却没钱买同样的鞋
いつも笑いのネ夕にして
这一直被我们当做笑料
いつか売れると信じてた
什么时候走红 我们期待着
客が2人の 演芸場で
在只有两个观众的剧场里

夢を托した100円を
把托付着梦想的一百元硬币
投げて真面目に拝んでる
投出去,一本正经地祈祷
顔に浮かんだ幼児の
你脸上浮现孩童般的纯真
無垢な心に またほれて
我再次被你吸引

1人訪ねたアパートで
独自去探访你的公寓
グラス傾け懐かしむ
相碰的酒杯间
そんな時代もあったねと
怀念从前我们也有那样的时代啊
笑い背中が揺れている
你抖着肩膀笑起来
夢は棄てたと 言わないで
不要说 我们已抛弃梦想
他にあてなき 2人なのに
我们本是 没有其他人可以依靠的两个人
夢は棄てたと 言わないで
不要说 我们已抛弃梦想
他に道無き 2人なのに
我们本是 没有其他人可以依靠的两个人

看《天注定》

Posted on 2019-01-30

写在最前

偶尔记录下平时看的电影~

关于天注定

这是贾樟柯的一部片子,斩获大奖却被禁了…当然看过之后就知道为啥被禁了,折射了太多的问题了…

  • 胡文海杀村官案
  • 周克华跨省抢劫案
  • 邓玉娇刺官案
  • 富士康十四连跳

记录了当代中国一个个脆弱的个体在面临不公走投无路从而诉诸血腥暴力的无奈悲剧(抄的)

大海

被压迫到最后只有诉诸暴力,但暴力之后也没有真正的自由。

小玉

一刀见血那一幕真的很有侠客的味道。

故事不知道该怎么说…

三儿

周克华事件,当时还在读初中..

他回到家里,看到些人觉得很没有意思,但这并不能成为杀人抢劫的理由。

小辉

希望在哪里?
希望在哪里?
希望在哪里?

观后感

很压抑。

当骨感的现实汹涌而来的时候,希望自己可以稳住,有可能的话,让这个世界更好一点点。

读《追风筝的人》

Posted on 2019-01-30

看完了《追风筝的人》的前半部分,有些压抑呀

少年之间的友谊,自私懦弱的少爷,忠心聪明的仆人,伊斯兰旗帜飘扬的中东…

那句“为你,千千万万遍”看得我很难受,休息两天再继续看吧。

update 20190215

在20190202天津飞往重庆的路上,一口气读完了剩下的部分,是真的好看,最后拯救孩子看得我眼角有点热。

ch10-时间序列

Posted on 2019-01-24
1
2
3
4
5
6
7
8
import numpy as np
import pandas as pd
np.random.seed(12345)
import matplotlib.pyplot as plt
plt.rc('figure', figsize=(10, 6))
PREVIOUS_MAX_ROWS = pd.options.display.max_rows
pd.options.display.max_rows = 20
np.set_printoptions(precision=4, suppress=True)

日期和时间数据类型及工具

1
2
3
from datetime import datetime
now = datetime.now()
now
datetime.datetime(2019, 1, 15, 0, 30, 21, 654285)
1
now.year,now.month,now.day
(2019, 1, 15)

datetime以毫秒格式存储日期和时间,也就是我们常用的timestamp

1
2
delta = datetime(2011,1,7) - datetime(2008,6,24,8,15)
delta
datetime.timedelta(926, 56700)
1
delta.days
926

可以给datatime对象+-一个或者多个timedelta

1
2
3
from datetime import timedelta
start = datetime(2011,1,7)
start + timedelta(1)
datetime.datetime(2011, 1, 8, 0, 0)

字符串和datetime的相互转换

1
2
stamp = datetime(2011,1,3)
stamp
datetime.datetime(2011, 1, 3, 0, 0)
1
str(stamp)
'2011-01-03 00:00:00'
1
stamp.strftime('%Y-%m-%d')   #跟hive类似
'2011-01-03'

dateutil很强

1
2
3
from dateutil.parser import parse

parse('2011-01-13')
datetime.datetime(2011, 1, 13, 0, 0)
1
parse('6/12/2015',dayfirst=True)
datetime.datetime(2015, 12, 6, 0, 0)
1
parse('Jan 31, 1997 10:45 PM')
datetime.datetime(1997, 1, 31, 22, 45)
1
2
datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00']
pd.to_datetime(datestrs)
DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00'], dtype='datetime64[ns]', freq=None)
1
2
idx = pd.to_datetime(datestrs + [None])
idx
DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00', 'NaT'], dtype='datetime64[ns]', freq=None)
1
idx.isnull()
array([False, False,  True])

时间序列基础

1
2
3
4
5
dates = [datetime(2011, 1, 2), datetime(2011, 1, 5),
datetime(2011, 1, 7), datetime(2011, 1, 8),
datetime(2011, 1, 10), datetime(2011, 1, 12)]
ts = pd.Series(np.random.randn(6), index=dates)
ts
2011-01-02   -0.204708
2011-01-05    0.478943
2011-01-07   -0.519439
2011-01-08   -0.555730
2011-01-10    1.965781
2011-01-12    1.393406
dtype: float64
1
type(ts)
pandas.core.series.Series
1
ts.index
DatetimeIndex(['2011-01-02', '2011-01-05', '2011-01-07', '2011-01-08',
               '2011-01-10', '2011-01-12'],
              dtype='datetime64[ns]', freq=None)
1
ts+ts[::2]
2011-01-02   -0.409415
2011-01-05         NaN
2011-01-07   -1.038877
2011-01-08         NaN
2011-01-10    3.931561
2011-01-12         NaN
dtype: float64
1
ts.index.dtype
dtype('<M8[ns]')
1
2
stamp = ts.index[0]
stamp
Timestamp('2011-01-02 00:00:00')
1
2
#传入一个被解释为日期的字符串
ts['2011-01-08']
-0.55573030434749

长序列可以之传入年 月等

1
2
long_ts = pd.Series(np.random.randn(1000),index = pd.date_range('1/1/2000',periods=1000))
long_ts.head()
2000-01-01   -1.613474
2000-01-02   -0.573966
2000-01-03    0.424894
2000-01-04    1.257544
2000-01-05   -1.065343
Freq: D, dtype: float64
1
long_ts['2001']
2001-01-01    0.590119
2001-01-02   -1.219580
2001-01-03    0.272788
2001-01-04   -2.691584
2001-01-05    1.567780
2001-01-06    0.265030
2001-01-07   -0.929412
2001-01-08    0.885587
2001-01-09   -1.557180
2001-01-10   -2.252237
                ...   
2001-12-22   -0.586346
2001-12-23    0.910428
2001-12-24   -0.573878
2001-12-25   -0.387236
2001-12-26   -0.857498
2001-12-27   -0.875737
2001-12-28   -0.075322
2001-12-29    0.325148
2001-12-30    1.699576
2001-12-31   -0.027604
Freq: D, Length: 365, dtype: float64

日期的范围,频率以及移动

1
ts.resample('D')
DatetimeIndexResampler [freq=<Day>, axis=0, closed=left, label=left, convention=start, base=0]

生成日期范围

pd.date_range()

1
pd.date_range('1/1/2011',periods=10)
DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04',
               '2011-01-05', '2011-01-06', '2011-01-07', '2011-01-08',
               '2011-01-09', '2011-01-10'],
              dtype='datetime64[ns]', freq='D')

频率和日期偏移量

1
2
3
from pandas.tseries.offsets import Hour, Minute
hour = Hour()
hour
<Hour>
1
pd.date_range('2000-01-01', '2000-01-03 23:59', freq='4h')
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 04:00:00',
               '2000-01-01 08:00:00', '2000-01-01 12:00:00',
               '2000-01-01 16:00:00', '2000-01-01 20:00:00',
               '2000-01-02 00:00:00', '2000-01-02 04:00:00',
               '2000-01-02 08:00:00', '2000-01-02 12:00:00',
               '2000-01-02 16:00:00', '2000-01-02 20:00:00',
               '2000-01-03 00:00:00', '2000-01-03 04:00:00',
               '2000-01-03 08:00:00', '2000-01-03 12:00:00',
               '2000-01-03 16:00:00', '2000-01-03 20:00:00'],
              dtype='datetime64[ns]', freq='4H')
1
Hour(2) + Minute(30)
<150 * Minutes>
1
pd.date_range('2000-01-01', periods=10, freq='1h30min')
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 01:30:00',
               '2000-01-01 03:00:00', '2000-01-01 04:30:00',
               '2000-01-01 06:00:00', '2000-01-01 07:30:00',
               '2000-01-01 09:00:00', '2000-01-01 10:30:00',
               '2000-01-01 12:00:00', '2000-01-01 13:30:00'],
              dtype='datetime64[ns]', freq='90T')

WOM日期

WOM(Week of Month),获得诸如‘每月第三个星期五’之类的日期

1
2
rng = pd.date_range('1/1/2012','9/1/2012',freq='WOM-3FRI')
rng
DatetimeIndex(['2012-01-20', '2012-02-17', '2012-03-16', '2012-04-20',
               '2012-05-18', '2012-06-15', '2012-07-20', '2012-08-17'],
              dtype='datetime64[ns]', freq='WOM-3FRI')

移动数据

1
2
3
ts = pd.Series(np.random.randn(4),
index=pd.date_range('1/1/2000', periods=4, freq='M'))
ts
2000-01-31    0.597205
2000-02-29    0.039901
2000-03-31   -0.757430
2000-04-30    1.698482
Freq: M, dtype: float64
1
ts.shift(2)
2000-01-31         NaN
2000-02-29         NaN
2000-03-31    0.597205
2000-04-30    0.039901
Freq: M, dtype: float64
1
ts.shift(-2)
2000-01-31   -0.757430
2000-02-29    1.698482
2000-03-31         NaN
2000-04-30         NaN
Freq: M, dtype: float64

时区处理

1
import pytz
1
pytz.common_timezones[-5:]
['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC']
1
2
tz=pytz.timezone('UTC')
tz
<UTC>
1
2
3
rng = pd.date_range('3/9/2012 9:30', periods=6, freq='D')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts
2012-03-09 09:30:00   -0.434694
2012-03-10 09:30:00    0.516461
2012-03-11 09:30:00   -0.153220
2012-03-12 09:30:00   -0.452038
2012-03-13 09:30:00    0.777409
2012-03-14 09:30:00   -0.163869
Freq: D, dtype: float64
1
pd.date_range('3/9/2012 9:30', periods=10, freq='D', tz='UTC')
DatetimeIndex(['2012-03-09 09:30:00+00:00', '2012-03-10 09:30:00+00:00',
               '2012-03-11 09:30:00+00:00', '2012-03-12 09:30:00+00:00',
               '2012-03-13 09:30:00+00:00', '2012-03-14 09:30:00+00:00',
               '2012-03-15 09:30:00+00:00', '2012-03-16 09:30:00+00:00',
               '2012-03-17 09:30:00+00:00', '2012-03-18 09:30:00+00:00'],
              dtype='datetime64[ns, UTC]', freq='D')

时期及其算术运算

to be add

记一次失眠

Posted on 2019-01-17

负重前行啊…

希望时间可以抚平伤痛。

Scrapy初体验

Posted on 2019-01-16

安装

我是pip3 install Scrapy一梭子完事,但是看文档貌似还要搞搞xcode…

可以参考官方文档Scrapy安装指南

初始化项目

1
scrapy startproject douban_book

scrapy会自动初始化一个目录,里面有一些必须的文件,其结构如下:

1
2
3
4
5
6
7
8
9
10
11
.
├── README.md
├── __init__.py
├── __pycache__
├── items.py
├── middlewares.py
├── pipelines.py
├── settings.py
└── spiders
├── __init__.py
└── __pycache__

  • scrapy.cfg: 项目的配置文件
  • items.py: 项目的目标文件
  • pipelines.py: 项目的管道文件
  • settings.py: 项目的设置文件
  • spiders: 爬虫代码目录

构建项目

定义数据

首先我们需要定义我们想要抓取什么数据,编辑item.py,Item定义结构化数据字段,用来保存爬取到的数据,有点像Python中的dict,但是提供了一些额外的保护减少错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class DoubanBookItem(scrapy.Item):

# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() #书名
link = scrapy.Field() #链接
author = scrapy.Field() #作者
score = scrapy.Field() #评分
scoreNum = scrapy.Field() #评论人数
press = scrapy.Field() #出版社
isbn = scrapy.Field() #isbn
price = scrapy.Field() #价格
publishyear = scrapy.Field() #出版年
authordesc = scrapy.Field() #作者简介
bookdesc = scrapy.Field() #书简介
label = scrapy.Field() #标签
pagecount = scrapy.Field() #字数
imgurl = scrapy.Field() #图片链接

编写爬虫

爬数据

我们需要用scrapy.Spider类创建一个子类,并为其确定三个强制的属性。

  • name = “” :这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
  • allow_domains = [] 是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略
  • start_urls = () :爬取的URL元祖/列表。爬虫从这里开始抓取数据,并根据子url继续往下爬。
1
2
3
name = "douban_book"
allowed_domains = ["douban.com"] #搜索的域名范围,也就是爬虫的约束区域
start_urls = ['https://book.douban.com/subject/25794620/']

取数据

parse()方法解析数据,这里运用了XPATH,虽然以前用的BeautifulSoup4,不过都是解析啦 这个问题不大。
chrome浏览器提供检查->选中元素->copy->XPATH的快捷方式获取这个,我写的时候一边写一边测试的。

1
2
3
4
#举个栗子
title = response.xpath("//div[@id='wrapper']/h1/span/text()").extract()
link = response.url
imgurl = response.xpath("//div[@id='mainpic']/a[@class='nbg']/@href").extract_first()

存储数据

现在我们已经获取我们想要的数据了,下一步就是把他们存下来,可以存成csv文件,或者直接存到数据库里。这里选择保存到MySQL。

在pipelines.py里定义process_item()方法,在这里可以对数据做一定的处理,比如缺失值异常值之类的,然后存入数据库。

1
2
3
4
5
6
7
8
def process_item(self, item, spider):
rep = re.compile('\n| ')
title = item.get('title','N/A')
author_tmp = item.get('author','N/A')
#省略一部分
sql = "replace into book_info (title,author,score,press,isbn,price,publishyear,label,pagecount) values (%s,%s,%s,%s,%s,%s,%s,%s,%s)"
self.cursor.execute(sql,(title,author,score,press,isbn,price,publishyear,label,pagecount))
self.conn.commit()

最终结果如下:

1
2
3
4
5
6
7
8
9
10
11
         id: 75
title: 沉默的大多数
author: 王小波
score: 9.1
scorenum: 0
press: 中国青年出版社
isbn: 9787500627098
price: 27.0000
publishyear: 1997-10
label: 王小波,杂文,沉默的大多数,思想,随笔,中国文学,文学,中国
pagecount: 555

ToDo

  • 页面解析并不是很好,经常缺数据
  • 加入redis
  • 会被封IP,需要加ip池

ch09-Example

Posted on 2019-01-14
1
2
3
4
5
6
7
8
9
import numpy as np
import pandas as pd
from pandas import Series
PREVIOUS_MAX_ROWS = pd.options.display.max_rows
pd.options.display.max_rows = 20
np.random.seed(12345)
import matplotlib.pyplot as plt
plt.rc('figure', figsize=(10, 6))
np.set_printoptions(precision=4, suppress=True)

1. 用特定于分组的值填充缺失值

gropna()可以实现,但也可以用fillna()方法填充。

1
2
3
s = Series(np.random.randn(6))
s[::2] = np.nan
s
0         NaN
1    0.228913
2         NaN
3    0.886429
4         NaN
5   -0.371843
dtype: float64
1
s.fillna(s.mean())
0    0.247833
1    0.228913
2    0.247833
3    0.886429
4    0.247833
5   -0.371843
dtype: float64
1
2
3
4
5
states = ['Ohio', 'New York', 'Vermont', 'Florida',
'Oregon', 'Nevada', 'California', 'Idaho']
group_key = ['East'] * 4 + ['West'] * 4
data = pd.Series(np.random.randn(8), index=states)
data
Ohio          1.669025
New York     -0.438570
Vermont      -0.539741
Florida       0.476985
Oregon        3.248944
Nevada       -1.021228
California   -0.577087
Idaho         0.124121
dtype: float64
1
data.groupby(group_key).mean()
East    0.291925
West    0.443688
dtype: float64
1
2
fill_mean = lambda g: g.fillna(g.mean())
data.groupby(group_key).apply(fill_mean)
Ohio          1.669025
New York     -0.438570
Vermont       0.569147
Florida       0.476985
Oregon        3.248944
Nevada        1.335928
California   -0.577087
Idaho         1.335928
dtype: float64
1
2
3
fill_values = {'East': 0.5, 'West': -1}
fill_func = lambda g: g.fillna(fill_values[g.name])
data.groupby(group_key).apply(fill_func)
Ohio          1.669025
New York     -0.438570
Vermont       0.500000
Florida       0.476985
Oregon        3.248944
Nevada       -1.000000
California   -0.577087
Idaho        -1.000000
dtype: float64

2. 随机采样和排列

构造一副扑克牌

1
2
3
4
5
6
7
8
9
10
11
# Hearts(红桃), Spades(黑桃), Clubs(梅花), Diamonds(方块)

suits = ['H','S','C','D']

card_val = (list(range(1,11))+[10]*3)*4
base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q']
cards = []
for suit in ['H', 'S', 'C', 'D']:
cards.extend(str(num) + suit for num in base_names)
deck = pd.Series(card_val, index=cards)
deck[:13]
AH      1
2H      2
3H      3
4H      4
5H      5
6H      6
7H      7
8H      8
9H      9
10H    10
JH     10
KH     10
QH     10
dtype: int64
1
2
3
def draw(deck, n=5):
return deck.sample(n)
draw(deck)
8S     8
8C     8
4C     4
QD    10
3C     3
dtype: int64
1
2
get_suit = lambda x:x[-1]
deck.groupby(get_suit).apply(draw,n=2)
C  2C     2
   4C     4
D  7D     7
   9D     9
H  JH    10
   9H     9
S  3S     3
   JS    10
dtype: int64

3. 分组加权平均数和相关系数

1
2
3
4
5
df = pd.DataFrame({'category': ['a', 'a', 'a', 'a',
'b', 'b', 'b', 'b'],
'data': np.random.randn(8),
'weights': np.random.rand(8)})
df
category data weights
0 a 0.388782 0.959661
1 a 0.940880 0.652225
2 a 1.660720 0.513206
3 a 0.642044 0.682356
4 b 0.418988 0.489540
5 b -0.259232 0.926490
6 b -0.369982 0.515880
7 b -0.044528 0.072160
1
2
3
grouped = df.groupby('category')
get_wavg = lambda g : np.average(g['data'],weights=g['weights'])
grouped.apply(get_wavg)
category
a    0.811113
b   -0.114339
dtype: float64

Yahoo!Finance数据实操

1
2
3
close_px = pd.read_csv('examples/stock_px_2.csv', parse_dates=True,
index_col=0)
close_px.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 2214 entries, 2003-01-02 to 2011-10-14
Data columns (total 4 columns):
AAPL    2214 non-null float64
MSFT    2214 non-null float64
XOM     2214 non-null float64
SPX     2214 non-null float64
dtypes: float64(4)
memory usage: 86.5 KB
1
close_px[-4:]
AAPL MSFT XOM SPX
2011-10-11 400.29 27.00 76.27 1195.54
2011-10-12 402.19 26.96 77.16 1207.25
2011-10-13 408.43 27.18 76.37 1203.66
2011-10-14 422.00 27.27 78.11 1224.58
1
spx_corr = lambda x: x.corrwith(x['SPX'])
1
rets = close_px.pct_change().dropna()
1
2
3
get_year = lambda x: x.year
by_year = rets.groupby(get_year)
by_year.apply(spx_corr)
AAPL MSFT XOM SPX
2003 0.541124 0.745174 0.661265 1.0
2004 0.374283 0.588531 0.557742 1.0
2005 0.467540 0.562374 0.631010 1.0
2006 0.428267 0.406126 0.518514 1.0
2007 0.508118 0.658770 0.786264 1.0
2008 0.681434 0.804626 0.828303 1.0
2009 0.707103 0.654902 0.797921 1.0
2010 0.710105 0.730118 0.839057 1.0
2011 0.691931 0.800996 0.859975 1.0

4. 面向分组的线性回归

1
2
3
4
5
6
7
8
import statsmodels.api as sm
def regress(data, yvar, xvars):
Y = data[yvar]
X = data[xvars]
X['intercept'] = 1.
result = sm.OLS(Y, X).fit()
return result.params
by_year.apply(regress, 'AAPL', ['SPX'])
SPX intercept
2003 1.195406 0.000710
2004 1.363463 0.004201
2005 1.766415 0.003246
2006 1.645496 0.000080
2007 1.198761 0.003438
2008 0.968016 -0.001110
2009 0.879103 0.002954
2010 1.052608 0.001261
2011 0.806605 0.001514

ch09-GroupBy

Posted on 2019-01-14

GroupBy技术

split->apply->combine

1
2
import numpy as np
import pandas as pd
1
2
3
4
5
df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)})
df
key1 key2 data1 data2
0 a one 1.587125 -0.517650
1 a two 0.206854 1.503013
2 b one 1.074688 -1.310088
3 b two 0.306591 2.236456
4 a one 0.462624 0.643336
1
2
3
#利用key1进行分组求data1的平均值
grouped = df['data1'].groupby(df['key1'])
grouped #一个groupby对象
<pandas.core.groupby.groupby.SeriesGroupBy object at 0x10637ba20>
1
grouped.mean()
key1
a    0.752201
b    0.690639
Name: data1, dtype: float64
1
grouped.describe()
count mean std min 25% 50% 75% max
key1
a 3.0 0.752201 0.734288 0.206854 0.334739 0.462624 1.024874 1.587125
b 2.0 0.690639 0.543127 0.306591 0.498615 0.690639 0.882664 1.074688
1
2
means = df['data1'].groupby([df['key1'],df['key2']]).mean()
means
key1  key2
a     one     1.024874
      two     0.206854
b     one     1.074688
      two     0.306591
Name: data1, dtype: float64
1
means.unstack()
key2 one two
key1
a 1.024874 0.206854
b 1.074688 0.306591
1
2
3
states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states, years]).mean()
California  2005    0.206854
            2006    1.074688
Ohio        2005    0.946858
            2006    0.462624
Name: data1, dtype: float64
1
df.groupby('key1').mean()
data1 data2
key1
a 0.752201 0.542900
b 0.690639 0.463184
1
df.groupby(['key1','key2']).mean()
data1 data2
key1 key2
a one 1.024874 0.062843
two 0.206854 1.503013
b one 1.074688 -1.310088
two 0.306591 2.236456

对分组进行迭代

1
2
3
4
5
#GroupBy对象支持迭代,可以产生一组二元元组

for name,group in df.groupby('key1'):
print(name)
print(group)
a
  key1 key2     data1     data2
0    a  one  1.587125 -0.517650
1    a  two  0.206854  1.503013
4    a  one  0.462624  0.643336
b
  key1 key2     data1     data2
2    b  one  1.074688 -1.310088
3    b  two  0.306591  2.236456
1
2
3
4
5
#多个键则返回由键值组成的元组

for name,group in df.groupby(['key1','key2']):
print(name)
print(group)
('a', 'one')
  key1 key2     data1     data2
0    a  one  1.587125 -0.517650
4    a  one  0.462624  0.643336
('a', 'two')
  key1 key2     data1     data2
1    a  two  0.206854  1.503013
('b', 'one')
  key1 key2     data1     data2
2    b  one  1.074688 -1.310088
('b', 'two')
  key1 key2     data1     data2
3    b  two  0.306591  2.236456
1
2
3
#造个字典
pieces = dict(list(df.groupby('key1')))
pieces['b']
key1 key2 data1 data2
2 b one 1.074688 -1.310088
3 b two 0.306591 2.236456

选取一个或者一列

1
df['data1'].groupby(df['key1']).describe()
count mean std min 25% 50% 75% max
key1
a 3.0 0.752201 0.734288 0.206854 0.334739 0.462624 1.024874 1.587125
b 2.0 0.690639 0.543127 0.306591 0.498615 0.690639 0.882664 1.074688
1
df.groupby(['key1'])['data1'].describe()  #单独选取‘data1’这一列
count mean std min 25% 50% 75% max
key1
a 3.0 0.752201 0.734288 0.206854 0.334739 0.462624 1.024874 1.587125
b 2.0 0.690639 0.543127 0.306591 0.498615 0.690639 0.882664 1.074688

通过字典或Series进行分组

1
2
3
4
5
people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
people.iloc[2:3, [1, 2]] = np.nan # Add a few NA values
people
a b c d e
Joe -0.323368 -0.768278 -0.169238 0.308583 -0.459496
Steve -0.597247 -0.301618 -0.439395 -1.482591 -0.019049
Wes 0.100330 NaN NaN 0.457292 1.192268
Jim -0.223226 -0.196377 2.264969 -0.982435 -1.851675
Travis -1.245037 -0.080968 -0.509985 0.928633 -0.474299
1
2
mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
'd': 'blue', 'e': 'red', 'f' : 'orange'}
1
2
by_columns = people.groupby(mapping,axis=1) #要和轴长度一致
by_columns.sum()
blue red
Joe 0.139345 -1.551143
Steve -1.921986 -0.917914
Wes 0.457292 1.292598
Jim 1.282534 -2.271279
Travis 0.418648 -1.800303

通过函数进行分组

1
people.groupby(len).sum()
a b c d e
3 -0.446265 -0.964655 2.095731 -0.216560 -1.118904
5 -0.597247 -0.301618 -0.439395 -1.482591 -0.019049
6 -1.245037 -0.080968 -0.509985 0.928633 -0.474299

根据索引级别分组

1
2
3
4
5
columns = pd.MultiIndex.from_arrays([['US', 'US', 'US', 'JP', 'JP'],
[1, 3, 5, 1, 3]],
names=['cty', 'tenor'])
hier_df = pd.DataFrame(np.random.randn(4, 5), columns=columns)
hier_df
cty US JP
tenor 1 3 5 1 3
0 -0.297194 0.028656 1.206242 1.330768 -0.267134
1 0.104323 -1.416412 -0.602244 -0.442782 -0.654808
2 1.199846 1.050484 0.077949 -0.214932 1.186233
3 0.214656 0.337322 -0.324943 1.581862 0.821636

数据聚合

主要讲sum(),count()等函数计算时到底发生了什么,我们也可以使用自己定义的聚合函数。

1
2
grouped = df.groupby('key1')
grouped['data1'].quantile(0.9)
key1
a    1.362225
b    0.997878
Name: data1, dtype: float64
1
grouped.describe().stack().head()
data1 data2
key1
a count 3.000000 3.000000
mean 0.752201 0.542900
std 0.734288 1.014069
min 0.206854 -0.517650
25% 0.334739 0.062843

分组运算和转换

1
#pass transform()

apply:一般性的‘拆分-应用-合并’

最一般化的GroupBy方法

1
2
3
tips = pd.read_csv('examples/tips.csv')
tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips[:6]
total_bill tip smoker day time size tip_pct
0 16.99 1.01 No Sun Dinner 2 0.059447
1 10.34 1.66 No Sun Dinner 3 0.160542
2 21.01 3.50 No Sun Dinner 3 0.166587
3 23.68 3.31 No Sun Dinner 2 0.139780
4 24.59 3.61 No Sun Dinner 4 0.146808
5 25.29 4.71 No Sun Dinner 4 0.186240
1
grouped = tips.groupby(['day', 'smoker'])
1
2
grouped_pct = grouped['tip_pct']
grouped_pct.agg('mean')
day   smoker
Fri   No        0.151650
      Yes       0.174783
Sat   No        0.158048
      Yes       0.147906
Sun   No        0.160113
      Yes       0.187250
Thur  No        0.160298
      Yes       0.163863
Name: tip_pct, dtype: float64
1
grouped_pct.agg(['mean', 'std'])
mean std
day smoker
Fri No 0.151650 0.028123
Yes 0.174783 0.051293
Sat No 0.158048 0.039767
Yes 0.147906 0.061375
Sun No 0.160113 0.042347
Yes 0.187250 0.154134
Thur No 0.160298 0.038774
Yes 0.163863 0.039389
1
grouped_pct.agg([('foo', 'mean'), ('bar', np.std)])  #传入tuple
foo bar
day smoker
Fri No 0.151650 0.028123
Yes 0.174783 0.051293
Sat No 0.158048 0.039767
Yes 0.147906 0.061375
Sun No 0.160113 0.042347
Yes 0.187250 0.154134
Thur No 0.160298 0.038774
Yes 0.163863 0.039389
1
2
3
functions = ['count', 'mean', 'max']
result = grouped['tip_pct', 'total_bill'].agg(functions)
result
tip_pct total_bill
count mean max count mean max
day smoker
Fri No 4 0.151650 0.187735 4 18.420000 22.75
Yes 15 0.174783 0.263480 15 16.813333 40.17
Sat No 45 0.158048 0.291990 45 19.661778 48.33
Yes 42 0.147906 0.325733 42 21.276667 50.81
Sun No 57 0.160113 0.252672 57 20.506667 48.17
Yes 19 0.187250 0.710345 19 24.120000 45.35
Thur No 45 0.160298 0.266312 45 17.113111 41.19
Yes 17 0.163863 0.241255 17 19.190588 43.11

分位数和桶分析

1
2
3
4
5
6
#和pandas的cut|qcut结合

frame = pd.DataFrame({'data1': np.random.randn(1000),
'data2': np.random.randn(1000)})
quartiles = pd.cut(frame.data1, 4)
quartiles[:10]
0    (-2.845, -1.307]
1      (0.225, 1.757]
2      (0.225, 1.757]
3      (0.225, 1.757]
4     (-1.307, 0.225]
5      (0.225, 1.757]
6      (0.225, 1.757]
7     (-1.307, 0.225]
8       (1.757, 3.29]
9     (-1.307, 0.225]
Name: data1, dtype: category
Categories (4, interval[float64]): [(-2.845, -1.307] < (-1.307, 0.225] < (0.225, 1.757] < (1.757, 3.29]]
1
2
3
4
5
def get_stats(group):
return {'min': group.min(), 'max': group.max(),
'count': group.count(), 'mean': group.mean()}
grouped = frame.data2.groupby(quartiles)
grouped.apply(get_stats).unstack()
count max mean min
data1
(-2.845, -1.307] 106.0 1.826602 0.117032 -2.382809
(-1.307, 0.225] 478.0 3.553988 0.079556 -2.690484
(0.225, 1.757] 379.0 2.647662 0.005168 -2.656434
(1.757, 3.29] 37.0 1.995249 0.024612 -1.838962

示例

后续补上

读《人间失格》

Posted on 2019-01-13

写在最前

记得很早之前看过一部电影《被嫌弃的松子的一生》,心里面觉得松子的可怜又可悲,末了再补上一句可怜之人必有可恨之处。电影里面松子遇到一个落魄的作家,偶像是太宰治,打她骂她辱她,却又爱她。

前几天看到太宰治的《人间失格》,想读一读。

作者背景

太宰治(1909-1948):

本名津岛修治,青森县人,父亲津岛原右卫门曾任众议院议员和贵族院议员,经营银行、铁路。太宰治是日本战后“无赖派”文学的代表作家,思想消沉、幻灭,不满现实的人生,几度自杀未果。一九三五年,他的短篇《逆行》入围第一届芥川奖,后因出版多部带有哀切的抒情作品而深受注目。一九三九年,他的《女生徒》获第四届北村透谷奖。一九四八年,他以《如是我闻》再度震惊文坛,并开始创作《人间失格》,书成之后,旋即投水自杀,结束了其灿烂多感而又凄美悲凉的一生。

如第一手札开篇所说:

我这一生,尽是可耻之事。

小感想

读《人间失格》的时候,心里面有点难受的感觉,但是也很理智地认识到这是这个我们不能帮助别人去改变的。日本独有的社会,个人特有的性格,造就了叶藏这个边缘人。写这个的时候BGM是《曾经我也想过一了百了》,心里面有些东西描述不出来,就算了吧。

大庭叶藏的悲剧不在于不能合群,不在于交友不慎,不在于吸毒,也不在于性关系混乱,而在于他本身失去了自我,这也是为什么叫《人间失格》吧。’生而为人,我很抱歉’,说得很到位了。

最后的最后看到作者这段话,想摘抄一下:

天使从空中飞过,听从神的旨意隐去双翅,像乘着降落伞一般飘落到世界的各个角落。我落在北国的学原,你落在南国的蜜柑田,而这群少年落在了上野公园。我们之间的差别仅仅如此。少年们啊,无论你们今后度过多少岁月,都请不要介意自己的容貌,不要吸食香烟,若非节日,也别喝酒。长大后,请多加爱惜那性格内向,不爱浓妆的姑娘。

此去黄泉无所愿,请君昂首直向前。

读《菜根谭》

Posted on 2019-01-11

写在最前

还是读点书修身养性比较好。

小记

《菜根谭》是一本语录体的书,可以想起来就读一点或者是放枕边,现在这里觉得好的对的就记录一下。虽然都是些大道理,但做人是要有方向的嘛。

处事篇

君子之心事,天青日白,不可使人不知;君子之才华,玉韫珠藏,不知使人易知。

心事看人,才华还是需要留一手的。

快意回首 拂心莫停
恩里由来生害,故快意时须早回首;败后或反成功,辜拂心处莫便放手。

跳出舒适区,披荆斩棘。

不恶小人 礼待君子

难

1…789…12
zhangyang

zhangyang

120 posts
39 tags
© 2022 zhangyang
Powered by Hexo
|
Theme — NexT.Mist v5.1.4