手机浏览器和pc浏览器的width:100%的自适应问题

thbcm阅读(227)

Tips: 调试 iPad 或 iPhone 可在设置中启动调试模式,在 Mac 中的 Safari 浏览器 一样开启开发者模式后,进行联机调试。功能彪悍。 最近在做一个页面时,发现在 iPad 的 Safari 浏览器中背景显示不全,定位到该 div 后发现所指定 css 的宽度为 100% ; 到百度搜索后发现,safari 中 viewport 默许宽度为 980px,若事前未指定其初始 viewport 宽度,则会默许依照 980px 处理。 可以默许初始化 viewport 宽度或在 css 中设定 min-width,但最简单的方法可以在 head 标签中初始化好 viewport。 

详见下方代码: <meta name=”viewport”content=”width=网页真实宽度, initial-scale=倍数值”/> 

假定网页宽度为 960px 或 1080px,可在 width 中加入该值,并将 initial-scale 设置一个合适的倍数值。 

例如一个页面的宽度为 1080px,则设定为: <meta name=”viewport”content=”width=1080, initial-scale=0.9″/> 这样不管加载前后切换横屏还是竖屏,都可以友好显示。

可是比如头部部份设置为  width:100%,而网页中部最大宽度为默许:1200px,头部和中部长度不一致。这个问题在 pc 端和手机的默许像素不一致造成。该如和解决?

在网页的<head>中增加以上这句话,可让网页的宽度自动适应手机屏幕的宽度:

<meta name=”viewport” content=”width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes” />     

<meta name=”apple-mobile-web-app-capable” content=”yes” />    

<meta name=”format-detection” content=”telephone=no” />    

第1行:

width=device-width :表示宽度是装备屏幕的宽度

initial-scale=1.0:表示初始的缩放比例

minimum-scale=0.5:表示最小的缩放比例

maximum-scale=2.0:表示最大的缩放比例

user-scalable=yes:表示用户是不是可以调剂缩放比例

第2行:

设定 iphone 端页面全屏。

第3行:

取消数字被辨认为电话号码。

如果是想要一打开网页,则自动以原始比例显示,并且不允许用户修改的话,则是:

<meta name=”viewport” content=”width=device-width(这里是可以变化的,根据你的其他div的宽度来设置), initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no” /> 

这模样写后,就能够把一些页头横幅等的图片的宽度都设置成 style=”width:100%”,全部页面在装备上看起来就是全屏的了。要把width=device-width 中的 device-width 换成你中部设置的像素值,比如我的设置为1200px, 这样问题就解决了。

JQuery Tips一些关于提高JQuery性能的Tips

thbcm阅读(181)

如今咱祖国已经崛起了..电脑的配置也是直线上升.可是 js 的性能问题依然不可小觑..尤其在万恶的 IE 中..js 引擎速度本来就慢..如果 JS 如果再写不好,客户端多开几个窗口假死肯定是家常便饭了.废话不说了,下面说说 js 性能提升的一些小 Tips.

在选择时,最好以 ID 选择符作为开头

我想这个很好理解,因为 JQuery 内部使用 document.getElementByID 方法进行 ID 选择,这种方法比其他所有对 DOM 选择的方法更快,所以以 $(“#”) 开头是最好的,比如:

<div id=”a”>

<div class=”b”>

<div class=”c”>

<div class=”d”></div>

</div>

</div>

</div>

<script type=”text/javascript”>

$(“.b .c .d”)//slow one

$(“#a .b .c .d”)//fast one

</script>

提供 $() 的上下文

在使用 $() 选择页面元素时,提供选择的范围可以减少选择的时间,换句话说,让选择器只在页面的一小片范围内筛选而不是整个页面当然会减少筛选时间,通过在 $() 函数内提供第二个参数作为上下文可以实现这一点

<div id=”test”>

<div class=”inner”>hi</div>

</div>

<script type=”text/javascript”>

alert($(“.inner”, document.getElementById(“test”)).text());//increase the speed by provide context

alert($(“.inner”).text());//traverse all the element so that is slower than above

</script>

当然,在 jquery 定义(或者js函数)事件内,可以通过 this 来指代上下文:

<div id=”test”>

<div class=”inner”>hi</div>

</div>

<script type=”text/javascript”>

$(“#test”).click(function() {

var text = $(“.inner”, this).text(); //this means $(“#test”)

alert(text);//alert hi

});

</script>

当然,上面的例子也可以写成下面两种方式:

<div id=”test”>

<div class=”inner”>hi</div>

</div>

<script type=”text/javascript”>

alert($(“#test .inner”).text()); //method 1

alert($(“#test”).find(“.inner”).text());//method 2 and it was best one

</script>

其中利用 find 方法是所有方法中效率最高的

当然,如果你是通过 id 选择符,也就是 $(“#..”)来选择,不需要提供上下文参数.这对速度没有影响

将经常用的 JQuery 包装好的元素进行保存

如题,这点比较重要,因为使用 $() 对页面元素进行选择是需要耗费时间的.而保存为变量进行使用时,可以避免这种浪费,比如:

<ul>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

</ul>

<script type=”text/javascript”>

for (i = 0; i < $(“ul li”).length; i++) {//very bad,select $(“ul li”) so many times,waste a lot of time

alert($(“ul li”)[i].innerHTML);//same here,very bad

}

var $li = $(“ul li”);

for (i = 0; i < $li.length; i++) {//good one,only selct $(“ul li”) once

alert($li[i].innerHTML); //same here,good

}

</script>

从代码可以看到,避免多次重复选择可以提高性能

尽量少用选择符

JQuery 的选择器是面向数组的,所以在条件允许的情况下尽量少用选择器,比如:

<div id=”Div0″></div>

<div id=”Div1″></div>

<div id=”Div2″></div>

<script type=”text/javascript”>

$(“#Div0”).slideDown(“slow”);

$(“#Div1”).slideDown(“slow”);

$(“#Div2”).slideDown(“slow”);//slow

$(“Div0,Div1,Div2”).slideDown(“slow”);//fast

</script>

可以看出,使用选择器并用逗号将被选择的元素分开,并选择多个元素不仅让代码更加简洁,并且通过减少创建 JQuery 的实例所以在性能上也稍胜一筹!

在循环次数很多时避免使用 $().each,而使用 for 循环

使用 $().each 方法让在进行循环时,会让编程更加轻松,少量的循环在使用 $().each 时对性能的影响可以忽略不计,但是当这个数字很大的时候,对性能的影响便开始变得可观了.

这个数字,我查了下资料,据说是1000以下可以使用 $().each 方法,而这个数字如果继续增加,则应该使用 for 循环语句。

尽量减少对 DOM 的操作

在页面中对 DOM 操作是比较消耗的(比如在页面插入或删除一段文字),把这个改动降至最小是保持性能的最佳实践!比如:

<ul id=”test”>

</ul>

<script type=”text/javascript”>

var $list = $(“#test”);

for (i = 1; i < 101; i++) {

$list.append(“<li>Item” + i + “</li>”);

} //very bad,change dom 100 times

var listItem = “”;

for (j = 1; j < 101; j++) {

listItem += “<li>Item” + j + “</li>”;

}

$list.html(listItem);

//good practice,only modify dom once

</script>

可以看出,第一个例子对 DOM 修改100次,而第二个只对 DOM 修改1次,这上面的性能差距是显而易见的。

可以屏蔽 JQuery 的动画效果

在某些情况下,如果,可以关闭 JQuery 动画,能对性能进行一定提升,屏蔽的方法是:

<script type=”text/javascript”>

jQuery.fx.off = true;

</script>

如果参数可以是 JS 对象,尽量使用对象

很对 JQuery 插件,或者 JQuery 的 css 和 attr 方法都接受键/值 或 js 键/值对象 对作为参数,传递键值对象可以减少 JQuery 对象的创建,比如:

<div></div>

<script type=”text/javascript”>

$(“div”).css(“display”, “block”);

$(“div”).css(“background-color”, “blue”)

//slow,because it create more Jquery object

$(“div”).css({ “display”: “block”, “background-color”: “blue” });

//fast,only create one object

</script>

当然也可以使用连缀的方式:

<div></div>

<script type=”text/javascript”>

$(“div”).css(“display”, “block”).css(“background-color”, “blue”);

</script>

但是这种方式的性能不如上面那种.需要使用两个方法,并且需要多生成临时对象.

以上都是一些对 JQuery 性能提升的小 Tips

推荐好课:jQuery微课jQuery从入门到精通

探秘B站2020年周热门视频(数据分析)

thbcm阅读(187)

1.数据抓取

数据集的获取是我们进行数据分析的第一步。现在获取数据的主要途径一般为:现成数据;自己写爬虫去爬取数据;使用现有的爬虫工具爬取所需内容,保存到数据库,或以文件的形式保存到本地。 

推荐阅读:Python 静态爬虫Python Scrapy网络爬虫

爬虫的设计思路

  1. 首先确定需要爬取网页 URL 地址 
  2. 通过 HTTP/HTTPS 协议来获取相应的 HTML 页面 
  3. 提取 HTML 页面里有用的数据 

       a. 如果是需要的数据就保存起来 

       b. 如果是页面里的其他 URL,那就继续执行第二步。

爬虫基本流程

发起请求 通过HTTP库向目标站点发起请求,就是发送一个 Request,请求可以包含额外的 header 等信息,等待服务器的响应 获取响应内容 如果服务器正常响应,会得到一个 Reponse, Reponse 的内容便是所要获取的页面内容,类型可能有 HTML,json 字符串,二进制数据(如图片视频)等类型。 解析内容 得到的内容可能是 HTML,可以用正则表达式,网页解析库进行解析,可能是 json,可以直接转为 JSON 解析对象解析,可能是二进制数据,可以做保存或者进一步处理。 保存数据保存的形式多种多样,可以保存成文本,也可以保存到数据库,或者保存特定格式文件

反爬虫机制与对策

机制

  1. 通过分析用户请求的Headers信息进行反爬虫。网站中应用的最多
  2. 通过验证用户行为进行反爬虫,不如通过判断同一个ip在短时间内是否频繁访问对应网站等进行分析。 
  3. 通过动态页面增加爬取的难度,达到反爬虫目的。

对策 

  1. 在爬虫中构造这些用户请求的 headers 信息,以此将爬虫伪装成浏览器 
  2. 使用代理服务器并经常切换代理服务器方式,一般就能够攻克限制。 
  3.  利用一些软件,比如selenium+phantomJS就可以攻克 反爬虫的手段 :user-agent、代理、验证码、动态数据加载、加密数据

数据的选择与处理

  1. 网页文本,如HTML文档 json格式文本 ;
  2. 图片,获取到的是二进制文件保存为图片格式 ;
  3. 视频 获取的二进制文件保存为视频格式即可; 
  4. 其他 只要能请求到的,都能获取 。

解析方式 

  1. 直接处理 
  2. json解析 
  3. 正则表达式 
  4. BeautifulSoup 
  5. PyQuery 
  6. XPath

2. 数据清洗

数据得到手,我们就需要对我们爬取的数据进行清洗工作,为之后的数据分析做铺垫,如果清洗的不到位势必会对之后的数据分析造成影响。 下文将从数据格式统一、空值处理。

推荐好课:Python3进阶:数据分析及可视化

格式统一

去掉数据的空格中,在用爬虫进行数据爬取时用 strip() 对爬取的字符串进行处理,将中文数据转换为阿拉伯数字。

例如1.7万变成17000,代码如下:

def get_int(s):

if s[-1]=="万":

    s=s[0:-1]

    s=int(float(s)*10000)

else:

    s=int(s)

return s

运行结果如下

if __name__ == '__main__':

    s="1.2万"

    price = get_int(s)

    print(price)#12000

空值处理

用爬虫对数据爬取的时候,若爬取的值不存在会报错,用异常处理语句 try{} except: pass (try 为爬取视频信息的代码),跳过不存在的视频信息数据。

try:

    html=requests.get(Link).text

    doc=BeautifulSoup(html);

    List=doc.find('div',{'class':'ops'}).findAll('span')

    like=List[0].text.strip()#点赞

    like=self.getint(like)

    coin=List[1].text.strip()#投币

    coin=self.getint(coin)

    collection=List[2].text.strip()#收藏

    collection=self.getint(collection)

    print('点赞',like)

    print('投币',coin)

    print('收藏',collection)

    # #将数据 拼合成字典 

    data={

        'Title':Title,

        'link':Link,

        'Up':Up,

        'Play':Play,

        'Like':like,

        'Coin':coin,

        'Collection':collection,

    }

    # 存储到csv文件

        self.write_dictionary_to_csv(data,'blibli2.csv')

        pass

    except:

        pass

3.数据分析及可视化

表格参数信息如图 

对视频排放量进行分析

对 B 站热门播放量进行分析,对 2020 年热门视频的播放量分为 4 个等级 一千万排放量以上为一个等级 五百万到一千万播放量为一个等级 五百万到一百万播放量为一个等级 一百万播放量以下为一个等级

l1=len(data[data['Play'] >= 10000000])

l2=len(data[(data['Play'] < 10000000) & (data['Play'] >=5000000)])

l3=len(data[(data['Play'] < 5000000) & (data['Play'] >=1000000)])

l4=len(data[data['Play'] < 1000000])

再数据通过 matplotlib 库进行可视化。得到下图。

plt.figure(figsize=(9,13)) #调节图形大小

labels = ['大于一千万','一千万到五百万','五百万到一百万','小于一百万'] #定义标签

sizes = [l1, l2, l3, l4] #每块值

colors = ['green', 'yellow', 'blue', 'red'] #每块颜色定义

explode = (0,0,0,0) #将某一块分割出来,值越大分割出的间隙越大

# 中文乱码和坐标轴负号处理

plt.rcParams['font.sans-serif'] = ['KaiTi']

plt.rcParams['axes.unicode_minus'] = False

patches,text1,text2 = plt.pie(sizes,

                      explode=explode,

                      labels=labels,

                      colors=colors,

                      autopct = '%3.2f%%', #数值保留固定小数位

                      shadow = False, #无阴影设置

                      startangle =90, #逆时针起始角度设置

                      pctdistance = 0.6) #数值距圆心半径倍数距离

#patches饼图的返回值,texts1饼图外label的文本,texts2饼图内部的文本

# x,y轴刻度设置一致,保证饼图为圆形

plt.axis('equal')

plt.title("B站热门播放量分布图")

plt.legend() # 右上角显示

plt.show()

从图中可以看出,在 B 站能上每周必看热门推荐的视频播放量大部分在五百万到一百万播放量,低于一百万播放量的视频很难上每周必看热门推荐,而一年中播放量达到于一千万的视频也很少。 让我们一起看看播放量排名前 10 的视频是那些好看的视频

data.nlargest(10,columns='Play') 

再数据通过 matplotlib 库进行可视化。得到下图。

d.plot.bar(figsize = (10,8),x='Title',y='Play',title='Play top 10')

plt.xticks(rotation=60)#夹角旋转60度

plt.show()

从图中可以看出哔哩哔哩拜年祭最受欢迎且播放量远远高于其它视频,说明B站2020年拜年祭节目进行的比较成功。

对作者进行分析

通过数据分析看那个作者的作品上热门次数最多,从而判断那个作者在2020年中最受欢迎。 对作者进行划分,统计出现的次数

d2=data.loc[:,'Up'].value_counts()

d2=d2.head(10)

再数据通过 matplotlib 库进行可视化。得到下图。

d2.plot.bar(figsize = (10,8),title='UP top 10')

plt.show()

说明 B 站上每周热门次数最多的作者是凉风 Kaze,一年 52 周热门推荐,一共出现了 48 次,几乎每周热门都有他的视频出现。从数据来看,2020 年最受欢迎的作者是凉风 Kaze。

对视频参数分析

对热门视频的点赞,投币,收藏平均比例进行分析

data['点赞比例'] = data['Like'] /data['Play']

data['投币比例'] = data['Coin'] /data['Play'] 

data['收藏比例'] = data['Collection'] /data['Play']

d3=data.iloc[:,8:11]

d3=d3.mean()

再数据通过 matplotlib 库进行可视化。得到下图。

d3.plot.bar(figsize = (10,8),title='UP top 10')

plt.show()

2020年中点赞比例最高,达到大约9%。说明在B站看视频的人,平均10个人中才会有一个人点赞。而平均平均20个人中才会有一个人对视频进行投币。

对标题进行分析

对标题高频次进行提取,看那类标题比较受欢迎 首先对所有标题进行遍历,储存在字符串s中

d4=data['Title']

s=''

for i in d4:

    s=s+i

然后用词云进行可视化 

标题中带有“朱一旦,半佛,罗翔”等作者名或“英雄联盟,原神”等游戏热门视频比较多。

EasyUI表单元素总结

thbcm阅读(179)

1.easyui-textbox 文本框

定义:

<input id="<span style="font-size:18px;">inputName</span>" class="easyui-textbox" type="text" />     

取值: $(‘#inputName’).textbox(‘getText’);

赋值: $(‘#inputName’).textbox(‘setText’, ‘liang’);

2.easyui-combobox 下拉框

定义:

<input id="<pre name="code" class="javascript">inputType

<class="easyui-combobox" data-options="required:true, panelHeight:60" />

初始化

$('#inputType').combobox( { data : getDictionaryDatas().Type, valueField : 'value', textField : 'label', missingMessage : messageCreator( ValidateMessage.msg_request_field, '类型') });

3.easyui-numberspinner 数字

定义:

<input id="ss" class="easyui-numberspinner" style="width:80px;" required="required" data-options="min:10,max:100,editable:false">

取值:

var v = $('#ss').numberspinner('getValue');

赋值:

$('#ss').numberspinner('setValue', 8234725);

4.datebox 日期

定义:

<input type="text" name="nn" id="nn" class="easyui-datebox" data-options="formatter:myDate.InitDateBox.formatter,parser:myDate.InitDateBox. parser" />

赋值:

$("#SC001_CERTIFICATEVALID").datebox('setValue', '2014⑼⑴2');

取值:

$('#nn').datebox('getValue'),

5.单选框

定义:

<td height="30" colspan="5">

<input type="radio" name="APPLYDEPTTYPE" value="事业法人" checked="checked" />事业法人

<input type="radio" name="APPLYDEPTTYPE" value="企业法人" />企业法人

<input type="radio" name="APPLYDEPTTYPE" value="社团法人" />社团法人

<input type="radio" name="APPLYDEPTTYPE" value="其他" />其他

</td>

赋值:

var str = result.APPLYDEPTTYPE; $("[value='" + str + "']").attr("checked", true);

取值:

$('input[name="APPLYDEPTTYPE"]:checked').val()

Pandas 分组聚合 懂?

thbcm阅读(195)

一:分组 (groupby)

  • 对数据集进行分组,然后对每组进行统计分析
  • SQL 能够对数据进行过滤,分组聚合
  • pandas 能利用 groupby 进行更加复杂的分组运算
  • 分组运算过程:split->apply->combine 拆分:进行分组的根据应用:每个分组运行的计算规则合并:把每个分组的计算结果合并起来

 

示例代码:

import pandas as pd
import numpy as np

dict_obj = {'key1' : ['a', 'b', 'a', 'b',
'a', 'b', 'a', 'a'],
'key2' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'data1': np.random.randn(8),
'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
print(df_obj)

运行结果:

      data1     data2 key1   key2
0 0.974685 -0.672494 a one
1 -0.214324 0.758372 b one
2 1.508838 0.392787 a two
3 0.522911 0.630814 b three
4 1.347359 -0.177858 a two
5 -0.264616 1.017155 b two
6 -0.624708 0.450885 a one
7 -1.019229 -1.143825 a three

一、GroupBy 对象:DataFrameGroupBy,SeriesGroupBy

1. 分组操作

groupby() 进行分组,GroupBy 对象没有进行实际运算,只是包含分组的中间数据按列名分组:obj.groupby(‘label’)

示例代码:

print(type(df_obj.groupby('key1'))) # dataframe根据key1进行分组
print(type(df_obj['data1'].groupby(df_obj['key1']))) # dataframe的 data1 列根据 key1 进行分组

运行结果:

<class 'pandas.core.groupby.DataFrameGroupBy'>
<class 'pandas.core.groupby.SeriesGroupBy'>

2. 分组运算

对 GroupBy 对象进行分组运算/多重分组运算,如 mean() 非数值数据不进行分组运算

示例代码:

grouped1 = df_obj.groupby('key1') # 分组运算
print(grouped1.mean())

grouped2 = df_obj['data1'].groupby(df_obj['key1'])
print(grouped2.mean())

运行结果:

         data1     data2
key1
a 0.437389 -0.230101
b 0.014657 0.802114
key1
a 0.437389
b 0.014657
Name: data1, dtype: float64

size() 返回每个分组的元素个数

示例代码:

print(grouped1.size()) # size
print(grouped2.size())

运行结果:

key1
a 5
b 3
dtype: int64
key1
a 5
b 3
dtype: int64

3. 按自定义的 key 分组

obj.groupby(self_def_key) 自定义的 key 可为列表或多层列表 obj.groupby([‘label1’, ‘label2’])->多层 dataframe

示例代码:

self_def_key = [0, 1, 2, 3, 3, 4, 5, 7] # 按自定义key分组,列表
print(df_obj.groupby(self_def_key).size())

print(df_obj.groupby([df_obj['key1'], df_obj['key2']]).size()) # 按自定义key分组,多层列表

grouped2 = df_obj.groupby(['key1', 'key2']) # 按多个列多层分组
print(grouped2.size())

grouped3 = df_obj.groupby(['key2', 'key1']) # 多层分组按key的顺序进行
print(grouped3.mean())

print(grouped3.mean().unstack()) # unstack可以将多层索引的结果转换成单层的dataframe

运行结果:

0    1
1 1
2 1
3 2
4 1
5 1
7 1
dtype: int64

key1 key2
a one 2
three 1
two 2
b one 1
three 1
two 1
dtype: int64


key1 key2
a one 2
three 1
two 2
b one 1
three 1
two 1
dtype: int64


data1 data2
key2 key1
one a 0.174988 -0.110804
b -0.214324 0.758372
three a -1.019229 -1.143825
b 0.522911 0.630814
two a 1.428099 0.107465
b -0.264616 1.017155

data1 data2
key1 a b a b
key2
one 0.174988 -0.214324 -0.110804 0.758372
three -1.019229 0.522911 -1.143825 0.630814
two 1.428099 -0.264616 0.107465 1.017155

二、GroupBy对象支持迭代操作

每次迭代返回一个元组 (group_name, group_data)可用于分组数据的具体运算

1. 单层分组

示例代码:

for group_name, group_data in grouped1: # 单层分组,根据key1
print(group_name)
print(group_data)

运行结果:

a      data1     data2 key1   key2
0 0.974685 -0.672494 a one
2 1.508838 0.392787 a two
4 1.347359 -0.177858 a two
6 -0.624708 0.450885 a one
7 -1.019229 -1.143825 a three

b
data1 data2 key1 key2
1 -0.214324 0.758372 b one
3 0.522911 0.630814 b three
5 -0.264616 1.017155 b two

2. 多层分组

示例代码:

for group_name, group_data in grouped2: # 多层分组,根据key1 和 key2
print(group_name)
print(group_data)

运行结果:

('a', 'one')
data1 data2 key1 key2
0 0.974685 -0.672494 a one
6 -0.624708 0.450885 a one

('a', 'three')
data1 data2 key1 key2
7 -1.019229 -1.143825 a three

('a', 'two')
data1 data2 key1 key2
2 1.508838 0.392787 a two
4 1.347359 -0.177858 a two

('b', 'one')
data1 data2 key1 key2
1 -0.214324 0.758372 b one

('b', 'three')
data1 data2 key1 key2
3 0.522911 0.630814 b three

('b', 'two')
data1 data2 key1 key2
5 -0.264616 1.017155 b two

三、GroupBy对象可以转换成列表或字典

示例代码:

print(list(grouped1)) # GroupBy对象转换list

print(dict(list(grouped1))) # GroupBy对象转换dict

运行结果:

[('a',       data1     data2 key1   key2
0 0.974685 -0.672494 a one
2 1.508838 0.392787 a two
4 1.347359 -0.177858 a two
6 -0.624708 0.450885 a one
7 -1.019229 -1.143825 a three),
('b', data1 data2 key1 key2
1 -0.214324 0.758372 b one
3 0.522911 0.630814 b three
5 -0.264616 1.017155 b two)]

{'a': data1 data2 key1 key2
0 0.974685 -0.672494 a one
2 1.508838 0.392787 a two
4 1.347359 -0.177858 a two
6 -0.624708 0.450885 a one
7 -1.019229 -1.143825 a three,
'b': data1 data2 key1 key2
1 -0.214324 0.758372 b one
3 0.522911 0.630814 b three
5 -0.264616 1.017155 b two}

1. 按列分组、按数据类型分组

示例代码:

print(df_obj.dtypes) # 按列分组

print(df_obj.groupby(df_obj.dtypes, axis=1).size()) # 按数据类型分组
print(df_obj.groupby(df_obj.dtypes, axis=1).sum())

运行结果:

data1    float64
data2 float64
key1 object
key2 object
dtype: object

float64 2
object 2
dtype: int64

float64 object
0 0.302191 a one
1 0.544048 b one
2 1.901626 a two
3 1.153725 b three
4 1.169501 a two
5 0.752539 b two
6 -0.173823 a one
7 -2.163054 a three

2. 其他分组方法

示例代码:

df_obj2 = pd.DataFrame(np.random.randint(1, 10, (5,5)),
columns=['a', 'b', 'c', 'd', 'e'],
index=['A', 'B', 'C', 'D', 'E'])
df_obj2.ix[1, 1:4] = np.NaN
print(df_obj2)

运行结果:

   a    b    c    d  e
A 7 2.0 4.0 5.0 8
B 4 NaN NaN NaN 1
C 3 2.0 5.0 4.0 6
D 3 1.0 9.0 7.0 3
E 6 1.0 6.0 8.0 1

3. 通过字典分组

示例代码:

mapping_dict = {'a':'Python', 'b':'Python', 'c':'Java', 'd':'C', 'e':'Java'} # 通过字典分组
print(df_obj2.groupby(mapping_dict, axis=1).size())
print(df_obj2.groupby(mapping_dict, axis=1).count()) # 非NaN的个数
print(df_obj2.groupby(mapping_dict, axis=1).sum())

运行结果:

C         1
Java 2
Python 2
dtype: int64

C Java Python
A 1 2 2
B 0 1 1
C 1 2 2
D 1 2 2
E 1 2 2

C Java Python
A 5.0 12.0 9.0
B NaN 1.0 4.0
C 4.0 11.0 5.0
D 7.0 12.0 4.0
E 8.0 7.0 7.0

4. 通过函数分组,函数传入的参数为行索引或列索引

示例代码:

 
df_obj3 = pd.DataFrame(np.random.randint(1, 10, (5,5)),
columns=['a', 'b', 'c', 'd', 'e'],
index=['AA', 'BBB', 'CC', 'D', 'EE']) # 通过函数分组

def group_key(idx): #df_obj3
"""
idx 为列索引或行索引
"""
#return idx
return len(idx)

print(df_obj3.groupby(group_key).size())

# 以上自定义函数等价于
#df_obj3.groupby(len).size()

运行结果:

1    1
2 3
3 1
dtype: int64

5. 通过索引级别分组

示例代码:

columns = pd.MultiIndex.from_arrays([['Python', 'Java', 'Python', 'Java', 'Python'],
['A', 'A', 'B', 'C', 'B']], names=['language', 'index']) # 通过索引级别分组
df_obj4 = pd.DataFrame(np.random.randint(1, 10, (5, 5)), columns=columns)
print(df_obj4)

print(df_obj4.groupby(level='language', axis=1).sum()) # 根据language进行分组

print(df_obj4.groupby(level='index', axis=1).sum()) # 根据index进行分组

运行结果:

language Python Java Python Java Python
index A A B C B
0 2 7 8 4 3
1 5 2 6 1 2
2 6 4 4 5 2
3 4 7 4 3 1
4 7 4 3 4 8

language Java Python
0 11 13
1 3 13
2 9 12
3 10 9
4 8 18

index A B C
0 9 11 4
1 7 8 1
2 10 6 5
3 11 5 3
4 11 11 4

二:聚合 (aggregation)

  • 数组产生标量的过程,如mean()、count()等
  • 常用于对分组后的数据进行计算

示例代码:

dict_obj = {'key1' : ['a', 'b', 'a', 'b', 
'a', 'b', 'a', 'a'],
'key2' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'data1': np.random.randint(1,10, 8),
'data2': np.random.randint(1,10, 8)}
df_obj5 = pd.DataFrame(dict_obj)
print(df_obj5)

运行结果:

   data1  data2 key1   key2
0 3 7 a one
1 1 5 b one
2 7 4 a two
3 2 4 b three
4 6 4 a two
5 9 9 b two
6 3 5 a one
7 8 4 a three

1. 内置的聚合函数

sum(), mean(), max(), min(), count(), size(), describe()

示例代码:

print(df_obj5.groupby('key1').sum())
print(df_obj5.groupby('key1').max())
print(df_obj5.groupby('key1').min())
print(df_obj5.groupby('key1').mean())
print(df_obj5.groupby('key1').size())
print(df_obj5.groupby('key1').count())
print(df_obj5.groupby('key1').describe())

运行结果:

      data1  data2
key1
a 27 24
b 12 18

data1 data2 key2
key1
a 8 7 two
b 9 9 two

data1 data2 key2
key1
a 3 4 one
b 1 4 one

data1 data2
key1
a 5.4 4.8
b 4.0 6.0

key1
a 5
b 3
dtype: int64

data1 data2 key2
key1
a 5 5 5
b 3 3 3

data1 data2
key1
a count 5.000000 5.000000
mean 5.400000 4.800000
std 2.302173 1.303840
min 3.000000 4.000000
25% 3.000000 4.000000
50% 6.000000 4.000000
75% 7.000000 5.000000
max 8.000000 7.000000
b count 3.000000 3.000000
mean 4.000000 6.000000
std 4.358899 2.645751
min 1.000000 4.000000
25% 1.500000 4.500000
50% 2.000000 5.000000
75% 5.500000 7.000000
max 9.000000 9.000000

2. 可自定义函数,传入agg方法中

grouped.agg(func)func的参数为groupby索引对应的记录

示例代码:

def peak_range(df): # 自定义聚合函数
"""
返回数值范围
"""
#print type(df) #参数为索引所对应的记录
return df.max() - df.min()

print(df_obj5.groupby('key1').agg(peak_range))
print(df_obj.groupby('key1').agg(lambda df : df.max() - df.min()))

运行结果:

      data1  data2
key1
a 5 3
b 8 5

data1 data2
key1
a 2.528067 1.594711
b 0.787527 0.386341
In [25]:

3. 应用多个聚合函数

同时应用多个函数进行聚合操作,使用函数列表

示例代码:

'''应用多个聚合函数

同时应用多个聚合函数'''
print(df_obj.groupby('key1').agg(['mean', 'std', 'count', peak_range])) # 默认列名为函数名

print(df_obj.groupby('key1').agg(['mean', 'std', 'count', ('range', peak_range)])) # 通过元组提供新的列名

运行结果:

         data1                                data2                           
mean std count peak_range mean std count peak_range
key1
a 0.437389 1.174151 5 2.528067 -0.230101 0.686488 5 1.594711
b 0.014657 0.440878 3 0.787527 0.802114 0.196850 3 0.386341

data1 data2
mean std count range mean std count range
key1
a 0.437389 1.174151 5 2.528067 -0.230101 0.686488 5 1.594711
b 0.014657 0.440878 3 0.787527 0.802114 0.196850 3 0.386341

4. 对不同的列分别作用不同的聚合函数,使用dict

示例代码:

dict_mapping = {'data1':'mean',
'data2':'sum'} # 每列作用不同的聚合函数
print(df_obj.groupby('key1').agg(dict_mapping))

dict_mapping = {'data1':['mean','max'],
'data2':'sum'}
print(df_obj.groupby('key1').agg(dict_mapping))

运行结果:

         data1     data2
key1
a 0.437389 -1.150505
b 0.014657 2.406341

data1 data2
mean max sum
key1
a 0.437389 1.508838 -1.150505
b 0.014657 0.522911 2.406341

5. 常用的内置聚合函数

 

示例代码:

import pandas as pd
import numpy as np

dict_obj = {'key1' : ['a', 'b', 'a', 'b',
'a', 'b', 'a', 'a'],
'key2' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'data1': np.random.randint(1, 10, 8),
'data2': np.random.randint(1, 10, 8)}
df_obj = pd.DataFrame(dict_obj)
print(df_obj)

k1_sum = df_obj.groupby('key1').sum().add_prefix('sum_') # 按key1分组后,计算data1,data2的统计信息并附加到原始表格中,并添加表头前缀
print(k1_sum)

运行结果:

   data1  data2 key1   key2
0 5 1 a one
1 7 8 b one
2 1 9 a two
3 2 6 b three
4 9 8 a two
5 8 3 b two
6 3 5 a one
7 8 3 a three

sum_data1 sum_data2
key1
a 26 26
b 17 17

聚合运算后会改变原始数据的形状,如何保持原始数据的形状?

1. merge

使用merge的外连接,比较复杂

示例代码:

k1_sum_merge = pd.merge(df_obj, k1_sum, left_on='key1', right_index=True) # 方法1,使用merge
print(k1_sum_merge)

运行结果:

   data1  data2 key1   key2  sum_data1  sum_data2
0 5 1 a one 26 26
2 1 9 a two 26 26
4 9 8 a two 26 26
6 3 5 a one 26 26
7 8 3 a three 26 26
1 7 8 b one 17 17
3 2 6 b three 17 17
5 8 3 b two 17 17

2. transform

transform的计算结果和原始数据的形状保持一致,如:grouped.transform(np.sum)

示例代码:

k1_sum_tf = df_obj.groupby('key1').transform(np.sum).add_prefix('sum_') # 方法2,使用transform
df_obj[k1_sum_tf.columns] = k1_sum_tf
print(df_obj)

运行结果:

   data1  data2 key1   key2 sum_data1 sum_data2           sum_key2
0 5 1 a one 26 26 onetwotwoonethree
1 7 8 b one 17 17 onethreetwo
2 1 9 a two 26 26 onetwotwoonethree
3 2 6 b three 17 17 onethreetwo
4 9 8 a two 26 26 onetwotwoonethree
5 8 3 b two 17 17 onethreetwo
6 3 5 a one 26 26 onetwotwoonethree
7 8 3 a three 26 26 onetwotwoonethree

也可传入自定义函数,

示例代码:

def diff_mean(s): # 自定义函数传入transform
"""
返回数据与均值的差值
"""
return s - s.mean()

print(df_obj.groupby('key1').transform(diff_mean))

运行结果:

      data1     data2 sum_data1 sum_data2
0 -0.200000 -4.200000 0 0
1 1.333333 2.333333 0 0
2 -4.200000 3.800000 0 0
3 -3.666667 0.333333 0 0
4 3.800000 2.800000 0 0
5 2.333333 -2.666667 0 0
6 -2.200000 -0.200000 0 0
7 2.800000 -2.200000 0 0

groupby.apply(func)

func函数也可以在各分组上分别调用,最后结果通过pd.concat组装到一起(数据合并)

示例代码:

import pandas as pd
import numpy as np

dataset_path = './starcraft.csv'
df_data = pd.read_csv(dataset_path, usecols=['LeagueIndex', 'Age', 'HoursPerWeek',
'TotalHours', 'APM'])

def top_n(df, n=3, column='APM'):
"""
返回每个分组按 column 的 top n 数据
"""
return df.sort_values(by=column, ascending=False)[:n]

print(df_data.groupby('LeagueIndex').apply(top_n))

运行结果:

                  LeagueIndex   Age  HoursPerWeek  TotalHours       APM
LeagueIndex
1 2214 1 20.0 12.0 730.0 172.9530
2246 1 27.0 8.0 250.0 141.6282
1753 1 20.0 28.0 100.0 139.6362
2 3062 2 20.0 6.0 100.0 179.6250
3229 2 16.0 24.0 110.0 156.7380
1520 2 29.0 6.0 250.0 151.6470
3 1557 3 22.0 6.0 200.0 226.6554
484 3 19.0 42.0 450.0 220.0692
2883 3 16.0 8.0 800.0 208.9500
4 2688 4 26.0 24.0 990.0 249.0210
1759 4 16.0 6.0 75.0 229.9122
2637 4 23.0 24.0 650.0 227.2272
5 3277 5 18.0 16.0 950.0 372.6426
93 5 17.0 36.0 720.0 335.4990
202 5 37.0 14.0 800.0 327.7218
6 734 6 16.0 28.0 730.0 389.8314
2746 6 16.0 28.0 4000.0 350.4114
1810 6 21.0 14.0 730.0 323.2506
7 3127 7 23.0 42.0 2000.0 298.7952
104 7 21.0 24.0 1000.0 286.4538
1654 7 18.0 98.0 700.0 236.0316
8 3393 8 NaN NaN NaN 375.8664
3373 8 NaN NaN NaN 364.8504
3372 8 NaN NaN NaN 355.3518

1. 产生层级索引:外层索引是分组名,内层索引是df_obj的行索引

示例代码:

print(df_data.groupby('LeagueIndex').apply(top_n, n=2, column='Age')) # apply函数接收的参数会传入自定义的函数中

运行结果:

                  LeagueIndex   Age  HoursPerWeek  TotalHours       APM
LeagueIndex
1 3146 1 40.0 12.0 150.0 38.5590
3040 1 39.0 10.0 500.0 29.8764
2 920 2 43.0 10.0 730.0 86.0586
2437 2 41.0 4.0 200.0 54.2166
3 1258 3 41.0 14.0 800.0 77.6472
2972 3 40.0 10.0 500.0 60.5970
4 1696 4 44.0 6.0 500.0 89.5266
1729 4 39.0 8.0 500.0 86.7246
5 202 5 37.0 14.0 800.0 327.7218
2745 5 37.0 18.0 1000.0 123.4098
6 3069 6 31.0 8.0 800.0 133.1790
2706 6 31.0 8.0 700.0 66.9918
7 2813 7 26.0 36.0 1300.0 188.5512
1992 7 26.0 24.0 1000.0 219.6690
8 3340 8 NaN NaN NaN 189.7404
3341 8 NaN NaN NaN 287.8128

2. 禁止层级索引, group_keys=False

示例代码:

print(df_data.groupby('LeagueIndex', group_keys=False).apply(top_n))

运行结果:

      LeagueIndex   Age  HoursPerWeek  TotalHours       APM
2214 1 20.0 12.0 730.0 172.9530
2246 1 27.0 8.0 250.0 141.6282
1753 1 20.0 28.0 100.0 139.6362
3062 2 20.0 6.0 100.0 179.6250
3229 2 16.0 24.0 110.0 156.7380
1520 2 29.0 6.0 250.0 151.6470
1557 3 22.0 6.0 200.0 226.6554
484 3 19.0 42.0 450.0 220.0692
2883 3 16.0 8.0 800.0 208.9500
2688 4 26.0 24.0 990.0 249.0210
1759 4 16.0 6.0 75.0 229.9122
2637 4 23.0 24.0 650.0 227.2272
3277 5 18.0 16.0 950.0 372.6426
93 5 17.0 36.0 720.0 335.4990
202 5 37.0 14.0 800.0 327.7218
734 6 16.0 28.0 730.0 389.8314
2746 6 16.0 28.0 4000.0 350.4114
1810 6 21.0 14.0 730.0 323.2506
3127 7 23.0 42.0 2000.0 298.7952
104 7 21.0 24.0 1000.0 286.4538
1654 7 18.0 98.0 700.0 236.0316
3393 8 NaN NaN NaN 375.8664
3373 8 NaN NaN NaN 364.8504
3372 8 NaN NaN NaN 355.3518

apply可以用来处理不同分组内的缺失数据填充 ,填充该分组的均值。

推荐好课:Python 自动化办公Python 自动化管理

Bootstrap–对移动设备友好的布局

thbcm阅读(176)

Bootstrap 有几个实用的用于开发对移动装备友好的布局的类。

.visible-phone:在宽度为 767px 及以下的手机上可见,在 979px 到 768px 的平板上隐藏不可见,在桌面上隐藏不可见,这是默许的。

.visible-tablet:在宽度为 767px 及以下的手机上隐藏不可见,在 979px 到 768px 的平板上可见,在桌面上隐藏不可见,这是默许的。

.visible-desktop:在宽度为 767px 及以下的手机上隐藏不可见,在 979px 到 768px 的平板上隐藏不可见,在桌面上可见,这是默许的。

.hidden-phone:在宽度为 767px 及以下的手机上隐藏不可见,在 979px 到 768px 的平板上可见,在桌面上可见,这是默许的。

.hidden-tablet:在宽度为 767px 及以下的手机上可见,在 979px 到 768px 的平板上隐藏不可见,在桌面上可见,这是默许的。

.hidden-desktop:在宽度为 767px 及以下的手机上可见,在 979px 到 768px 的平板上可见,在桌面上隐藏不可见,这是默许的。

我们直接上代码:

<!doctype html> 
<html> 
<head> 
<meta charset="utf⑻"> 
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
<title>响应式布局的实用类</title> 
<link href="../bootstrap/css/bootstrap.css" rel="stylesheet"> 
<link href="../bootstrap/css/bootstrap-responsive.css" rel="stylesheet"> <!--[if lt IE 9]> 
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> 
</head> 
<body> 
<div class="container"> 
<h1 class="page-header">响应式布局的实用类
<small> 使用Bootstrap网格系统布局网页</small></h1> 
<div class="row"> 
<div class="page-header clearfix"> 
<div class="span4">
<img src="images/phone.png" alt="智能手机"></div> 
<div class="span4 hidden-phone">
<img src="images/tablet.png" alt="平板电脑"></div> 
<div class="span4"><img src="images/desktop.png" alt="桌面电脑"></div> 
</div> </div> </div> 
<script src="../bootstrap/js/jquery⑴.7.2.min.js"></script> 
<script src="../bootstrap/js/bootstrap.js"></script> 
</body> 
</html>

pandas的文件读取和保存

thbcm阅读(180)

一、Excel 文件的读取(read_excel)

pd.read_excel(io, sheetname=0, header=0, skiprows=None, skip_footer=0, index_col=None, names=None, parse_cols=None, parse_dates=False, date_parser=None, na_values=None, thousands=None, convert_float=True, has_index_names=None, converters=None, dtype=None, true_values=None, false_values=None, engine=None, squeeze=False, **kwds)

参数说明:

  • io: 字符串,文件的路径对象

  • sheetname:None、string、int、字符串列表或者是整数列表,default 为 0,字符串用于工作表名称,整数用于零索引工作表位置,字符串列表或整数列表用于请求多个工作表,为 None 时获取所有工作表。

sheetname 值的描述
0 获取sheet1表格
1 获取sheet2表格
‘Sheet3’ 获取sheet3表格
[0,1,‘Sheet5’] 获取sheet1,sheet2和sheet5表格
  • header: 表示的是哪一行作为列索引,默认是 0 (第一行), 当 header 不为第一行的时候,会将默认为列索引之前的行全部删除不读,数据为列名行以下的数据;若数据不含列名,则设定 header = None。

  • names:当文件中没有给出表头的时候,需要将 header 设置为 None 值, 并且传入与列相同数量的 list

    data = pd.read_excel(r'C:\w3cschool\learn\text\hello_w3cschool.xlsx',header=None,names=np.arange(19))
    print(data.head())
    
  • index_col:指定列为索引列,默认 None 列(0 索引)用作 DataFrame 的行标签。\

  • skiprows : 跳过指定行(包括)之前的行开始读取

    • 传入的值从 1 开始的任意 int 类型,超出行的长度不报错,显示为空,如下:
      Empty DataFrame
      Columns: []
      Index: []

    • 只剩最后一条数据时,显示如下:
      Empty DataFrame
      Columns: [4, peter, 18, man]
      Index: []
      nrows

    • 值为int类型,默认None,只取前n行数据,按索引传参

    • 传入值为0时,只取第一行,显示如下:
      Empty DataFrame
      Columns: [1, jack, 22, man]
      Index: []

    • 传入其余值时,只显示该值(包括)之前的行,超出行的长度后不报错,有多少行显示多少行

二、读取 csv 文件( read_csv )

注释:.csv 属于文本文件,逗号分隔文件,编码一般为 gbk;

参数说明:

  1. sep: 元素之间分隔符,csv文件默认分隔符为逗号;
  2. engine: {‘c’, ‘python’},底层编译的方式,默认是c语言,如果遇到问题,可以将 engine 改为 Python;
  3. encoding: 一般是gbk
  4. delimiter: str, default None, 定界符,备选分隔符(如果指定该参数,则 sep 参数失效)

pd.read_table( r’path’,
sep=’,’,
encoding=‘gbk’,
engine=‘python’).head()

三、文件的保存

(1)保存到 excel 文件: to_excel

参数说明:

  • excel_writer: 字符串或 Excelwrite 对象,文件路径或现有的 ExcelWriter
  • sheet_name: 字符串,默认’Sheet1’
  • na_rep: 字符串,默认’ ‘,缺失数据表示

df.to_excel(‘filename.xlsx’)

(2)保存到 csv 文件: to_csv

参数说明:

  • path_or_buf: 默认值为None,字符串或文件句柄,默认无文件,路径或对象,如果没有提供,结果将返回为字符串.
  • sep: 输出文件的字段的分隔符,默认为 ’,’
  • na_rep: 缺失数据表示,默认为 ’ ’

,默认无文件,路径或对象,如果没有提供,结果将返回为字符串.

  • sep: 输出文件的字段的分隔符,默认为 ’,’
  • na_rep: 缺失数据表示,默认为 ’ ’

Google的软件工程师面试流程

thbcm阅读(195)

从申请到录用-您需要了解有关Google录用过程的所有信息。

原文:Levels.fyi

作者:匿名(前谷歌HR)

翻译:W3Cschool编程狮

通过握手交付工作机会的日子已经一去不复返了。对于在科技公司面试的应聘者,预计多步骤面试过程跨越数周(4到6周),甚至是几个月。缩小科技公司的范围,下面是对谷歌软件工程师面试过程的深入探讨。以下表示直接申请公开职位申请的一般软件工程候选人或当前 Google 人员推荐的应聘者的流程。如果招聘人员主动联系了应聘者,或者他们申请了特定的团队或领域,则流程可能略有不同。

简历审查

与普遍的看法相反,Google 的所有简历均由专人来进行审查。神奇的 ATS 不会随意淘汰简历,有专门的团队来负责审查简历。他们根据职位描述的最低和首选资格评估简历。所有符合职位描述最低要求的简历都将被考虑在内。如果某个特定职位有很多人申请,而且大多数人都符合要求(Google 在 2019 年收到了 330 万份申请 与 2018 年相比增长了 18%。)的时候,一两个亮点也可能成为候选因素,通常这是唯一考虑简历的时间(尽管如果收到邀约,则所有信息都将得到验证)。许多面试官在与候选人见面之前并不会审查简历。他们更注重真实的技术能力,而不是审查赞誉。如果简历上满是绒毛,以后就会变得明显。

电话面试

首先,招聘协调员将组织对软件工程师(SWE)的电话面试。面试计划持续 45 分钟,其中编码练习约40分钟,考生提问时间约5分钟。在电话面试的当天,SWE 会通过电话给应聘者(TC)打电话,要求他们打开 Google 共享文档,并指示应聘者响应并完成算法编码练习。

电话面试后,要求面试官在 48 小时内提交书面反馈。面试官的评分为:

  • 推荐雇佣(SH)
  • 雇用(H)
  • 可雇用(LH)
  • 可不雇佣(LNH)
  • 不雇佣(NH)
  • 绝不雇用(SNH)

理想情况下,获得 SH 或 H 评分会进入下一轮面试。LH 和 LNH 也可能会获得下一轮面试机会,具体取决于面试官的书面反馈。获得 NH 和 SNH 评分就到此结束了,基本不会进入下一轮面试。

Google 使用“结构化面试 ”方法,这意味着所有候选者都将获得清晰、标准化的评价,因此面试反馈和分数不会造成混淆。尽管技术能力对于面试过程中的成功至关重要,但缺乏诚意或沟通技巧不足也可能会阻碍应聘者的发展。Google 专注于招聘能在团队中自主运作的全面人才。

现场面试

如果应聘者的分数值得进入下一步,招聘人员将邀请他们进行现场面试(从2020年4月开始,所有现场面试现在都是数字化的,并通过 Google 环聊进行)。招聘人员应提供面试准备电话,以帮助应聘者准备。如果他们没有,需要提供。招聘人员将深入了解评估领域,并帮助应聘者了解面试官用于评分答案的框架。

在此阶段,将进行五次时长45分钟的面试,并举行一次非正式午餐会。级别决定涵盖哪些评估区域。

3级和4级面试

  • 4/5 数据结构和算法
  • 1/5 Googleyness 和领导力

5级和6级面试

  • 3/5 数据结构和算法
  • 1/5 系统设计
  • 1/5 Googleyness和领导力

通常,会进行两三个面试,午休时间,然后是最后的两三个面试。

现场面试往往是电话面试的更深入版本。面试官通常问两个问题,而不是一个编码问题。午餐会不由 Google 评估或评分。它的目的是让考生有机会在更轻松的环境中提问,看看校园生活和谷歌文化是什么样的。

与电话面试类似,面试官被要求在现场面试后 48 小时内提交书面反馈。然而,它往往需要更长的时间,一般需要7天左右。面试官使用上述相同的标准评分系统来评估应聘者资格。面试完成后,招聘人员将审核反馈,并确定进入下一步是否有意义。反馈不一或结果无定论的应聘者可能会被要求进行后续面试。

招聘委员会

面试结果令人满意的应聘者将提交给招聘委员会。招聘委员会(HC)是一组高级 SWE,负责审核面试数据包(数据包可以包括:简历,面试成绩,内部 Google 员工推荐,招聘经理的支持声明等)。HC 被指示对数据包进行筛查,以发现面试官可能遗漏的不一致、偏见或任何其他危险信号。委员会中的每个 SWE(通常有三个)审查信息,并给数据包一个雇用,保留或拒绝评级。委员会成员有机会讨论其决定背后的理由,并经常相互辩论。HC 由招聘人员进行调解,该招聘人员奉命在遵守具体招聘准则的同时,也指出 HC 成员评论和职位中的偏见。委员会成员在 HC 会议上可以更改其评级,但会议闭幕后不能更改评级。

所有委员会成员必须支持被录用的应聘者。如果有一个成员存疑,可能会要求应聘者进行后续面试以解决关切领域。后续面试结束后,他们的包裹将被寄回委员会进行第二次审查。但是,如果数据包获得批准,应聘者将进入流程的最后步骤!

合适的电话和团队配对

在招聘委员会批准之后,您的招聘人员将根据您的级别和位置偏好确定公开职位。(如果您要面试某个特定的角色/团队,则可能会跳过此步骤)。Fit Call 是与招聘经理进行的 30 到 45 分钟的通话。本质上,这是一次非正式的电话会议,为应聘者和招聘经理提供了联系,讨论团队/项目并确定双方是否有共同利益的机会。在找到一个匹配项之前,通常需要进行几次拟合调用。有时候,招聘人员无法立即为获批准的应聘者找到团队或合适的角色。面试成绩的有效期为一年,因此,如果出现招聘暂停或延迟的情况,应聘者无需完成其他面试即可获得相匹配的类似职位。

提供

报价由特定的薪酬团队产生,该团队审查应聘者的级别和位置以确定薪酬方案。产生报价后,招聘人员将致电以提供口头报价,并通过电子邮件以书面形式确认该信息。双方就补偿方案达成协议后,将发送正式的录取通知书以供签署。最后,该庆祝了!

Python递归和生成器实现斐波那契数列区别

thbcm阅读(242)

前言

斐波那契数列,又称黄金分割数列,又名兔子数列。

通俗的来说,即从该数列中的第三项开始,后面的每一个数的值等于前两个数的和。

而我们通过 python 如何来实现不同长度的斐波那契数列呢?
常见的实现方法有递归和生成器。

那么小编今天就为大家介绍用这两种方式实现斐波那契数列的区别。

推荐阅读:Python3 入门Python3 进阶

递归

递归的方法效率较低,会出现大量重复计算,这里以 20 个斐波那契数列为例。

def fbnq_one(self):

    if self == 1:

        return 1

    elif self == 2:

        return 2

    else:

        return fbnq_one(self - 2) + fbnq_one(self - 1)

print([fbnq_one(i) for i in range(1, 21)])

生成器

生成器需要在方法中运用 yield,生成器是一个可迭代对象,可以遍历获取元素,在获取较多斐波那契数列时,相比递归效率较高,这里以 100 个斐波那契数列为例。

def fbnq_two(max_num):

    a, b = 0, 1

    time_num = 0

    while time_num < max_num:

        yield a

        a, b = b, a+b

        time_num += 1

print([i for i in fbnq_two(100)])

比较

递归语法简单,但执行起来,重复计算多,数值一大,运行时间就变长;
生成器可以遍历获取元素,在获取较多斐波那契数列时,相比递归效率较高,运行时间相对更快。

ECharts案例教程

thbcm阅读(195)

简介

ECharts(Enterprise Charts,商业级数据图表)是百度的一个开源的数据可视化工具,底层基于 ZRender(一个全新的轻量级 canvas 类库),可以比较方便的折线图、柱状图、散点图、K 线图、饼图、雷达图、地图、和弦图、力导向布局图、仪表盘和漏斗图,同时支持任意维度的堆积和多图表混合展现等。

案例欣赏

本案例为具有时间轴的折线系列图,合适用于对照展现数据,比如某超市年度销量变化图,某产品的前期投入资金图等。

知识储备

1.标签式单文件引入Echarts。

官方推荐三种使用引入 ECharts 的方式,模块化包引入、模块化单文件引入和标签式单文件引入。首篇博客采取了模块化单文件引入的方式,这类方式可以按需加载文件,是官方推荐的方式。本文我们将使用标签式单文件引入的方式,如果你的项目没有基于模块化开发,同时也不基于 AMD 规范,那末使用标签式单文件方式将会非常方便,我们只需要使用 script 标签引入一个 ECharts 库便可,可引入的单文件包括:dist/echarts-all.js 和 source/echarts-all.js。前者经过紧缩,包括全图表,包括 world,china 和34个省市级地图数据;后者未紧缩,包括全图表,包括 world,china 和34个省市级地图数据,可用于调试。

2.时间轴控件的使用。

使用时间轴控件,我们需要从两个方面做准备,一个是设置时间轴,一个是设置每一个时间点(数据和标题等)。

设置时间轴。时间轴在 ECharts 里使用 timeline 设置,每一个图标最多只能具有一个时间轴,主要参数以下。

分组 参数 类型 默许值 含义
参数设置 data Array [] 时间轴列表,同时也是轴label内容
show boolean true 显示策略,可选为:true(显示) | false(隐藏)
type string ‘time’ 模式是时间类型,时间轴间隔根据时间跨度计算,可选为:’number’
notMerge boolean false 时间轴上多个option切换时是不是进行merge操作,同setOption第2个参数(详见实例方法)
realtime boolean true 拖拽或点击改变时间轴是不是实时显示,在不支持Canvas的阅读器中该值自动强迫置为false
播放控制 autoPlay boolean false 是不是自动播放
loop boolean true 是不是循环播放
playInterval number 2000 播放时间间隔
currentIndex number 0 当前索引位置,对应options数组,用于指定显示特定系列
样式设置 width number|string 自适应 时间轴宽度,默许为总宽度 – x – x2,指定width后将疏忽x2。
height number|string 50 时间轴高度
x number|string 80 时间轴左上角横坐标
y number|string null 时间轴左上角纵坐标,默许无,随y2定位,
x2 number|string 80 时间轴右下角横坐标
y2 number|string 0 时间轴右下角纵坐标
padding number|Array 5 内边距,单位px,接受数组分别设定上右下左侧距,同css。
backgroundColor color ‘rgba(0,0,0,0)’ 背景色彩,默许透明。
borderWidth number 0 边框线宽
borderColor color ‘#ccc’ 边框色彩
controlPosition string ‘left’ 播放控制器位置,可选为:’left’ | ‘right’ | ‘none’
lineStyle Object 参见代码 时间轴轴线样式,lineStyle控制线条样式,(详见lineStyle)
label Object 参见代码 时间轴标签文本
checkpointStyle Object 参见代码 时间轴当前点
controlStyle Object 参见代码 时间轴控制器样式,可指定正常和高亮色彩
symbol string ’emptyDiamond’ 轴点symbol,同serie.symbol
symbolSize number 4 轴点symbol,同serie.symbolSize

注意:

a++. width、height、x、x2、y、y2等设置大小位置的参数,类型为 number|string,可以接受数值型,单位为 px,也可接受百分比(字符串),如50%表示居中显示。

b++. lineStyle 的默许值为{color: ‘#666’, width: 1, type: ‘dashed’}

c++. label 的默许值为代码所示。参数解释以下

show : 是不是显示 ;

interval : 挑选间隔,默许为’auto’,可选为:’auto’(自动隐藏显示不下的) | 0(全部显示) | {number} ;

rotate : 旋转角度,默许为0,不旋转,正值为逆时针,负值为顺时针,可选为:⑼0 ~ 90 ;

formatter : 间隔名称格式器:{string}(Template) | {Function} ;

textStyle : 文字样式(详见textStyle)

{ show: true, interval: 'auto', rotate: 0, formatter: null, textStyle: { color: '#333' } }

d++. checkpointStyle 的参数解释以下,默许值为代码所示。

symbol : 当前点 symbol,默许随轴上的 symbol 

symbolSize : 当前点 symbol 大小,默许随轴上 symbol 大小 

color : 当前点 symbol 色彩,默许为随当前点色彩,可指定具体色彩,如无则为’#1e90ff’ 

borderColor : 当前点 symbol 边线色彩 

borderWidth : 当前点 symbol 边线宽度 

label 同 c

{ symbol : 'auto', symbolSize : 'auto', color : 'auto', borderColor : 'auto', borderWidth : 'auto', label: { show: false, textStyle: { color: 'auto' } } }

e++. controlStyle 的默许值为

{ normal : { color : '#333'}, emphasis : { color : '#1e90ff'} }

样式参数在时间轴上的作用效果见下图详视。

设置每一个时间点。第2步是设置每一个具体的时间点,每一个时间点就是1个图标,包括标题、图例、坐标轴、数据等,固然一般坐标轴、图例等不变,仅仅改变标题和数据。

var option = { //时间轴设置 timeline : {}, //时间点设置 options : [ //第1个时间点 {}, //第2个时间点 {}, //... ] }

实现进程

然后我们来解读实现进程。

时间轴里面我们设置了时间戳,仅仅显示年份;为保证美观,调剂了时间轴的位置;同时设定了时间轴播放设置。

var option = { 
//时间轴设置 timeline : { 
//时间轴时间列表 data:[ '2002-01-01','2003-01-01','2004-01-01','2005-01-01','2006-01-01' ], 
//自定义处理,只显示年份 label:{ formatter : function(s) { return s.slice(0, 4); } }, 
//时间轴的位置设定 height:80, x:50, padding:[40,10,10,10], 
//时间轴播放控制 autoPlay : true, playInterval : 2000 }, 
//时间点设置 options : [ //第1个时间点 {}, //第2个时间点 {}, //... ] }

然后设置时间点,先看2012年的数据设置,我们设置标题、提示、图例、坐标轴、绘制数据线。

var option = { 

//时间轴设置 timeline : { 

//时间轴时间列表 data:[ '2002-01-01','2003-01-01','2004-01-01','2005-01-01','2006-01-01' ], //自定义处理,只显示年份 label:{ formatter : function(s) { return s.slice(0, 4); } }, 

//时间轴的位置设定 height:80, x:50, padding:[40,10,10,10], 

//时间轴播放控制 autoPlay : true, playInterval : 2000 }, 

//时间点设置 options : [ 

//第1个时间点 

//2002年数据表,新增内容 { title:{ text:'2002年货物销量图', subtext:'纯属捏造,如有雷同,人品爆发。' }, //设置提示 tooltip: { show: true }, 

//设置图例 legend: { data:['销量'] }, 

//设置坐标轴 xAxis : [ { type : 'category', data : ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子","帽子","围巾"], axisLabel:{ margin:⑵0, textStyle:{ color:'#999', fontWeight:'bold' } } } ], yAxis : [ { type : 'value' } ], series : [ { type:'line', data:[5, 20, 38, 10, 24, 20,24,32], 

//绘制平均线 markLine : { data : [ {type : 'average', name: '平均值'} ] }, 

//绘制最高最低点 markPoint : { data : [ {type : 'max', name: '最大值'}, {type : 'min', name: '最小值'} ] } } ] }, 

//第2个时间点 {}, //... ] }

其他时间点只需要设置于2002年不同的地方便可,本例我们仅仅设置标题和数据表。

var option = { 

//时间轴设置 timeline : { 

//时间轴时间列表 data:[ '2002-01-01','2003-01-01','2004-01-01','2005-01-01','2006-01-01' ], 

//自定义处理,只显示年份 label:{ formatter : function(s) { return s.slice(0, 4); } }, 

//时间轴的位置设定 height:80, x:50, padding:[40,10,10,10], 

//时间轴播放控制 autoPlay : true, playInterval : 2000 }, 

//时间点设置 options : [ 

//第1个时间点 

//2002年数据表 { title:{ text:'2002年货物销量图', subtext:'纯属捏造,如有雷同,人品爆发。' }, 

//设置提示 tooltip: { show: true }, 

//设置图例 legend: { data:['销量'] }, 

//设置坐标轴 xAxis : [ { type : 'category', data : ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子","帽子","围巾"], axisLabel:{ margin:⑵0, textStyle:{ color:'#999', fontWeight:'bold' } } } ], yAxis : [ { type : 'value' } ], series : [ { type:'line', data:[5, 20, 38, 10, 24, 20,24,32], 

//绘制平均线 markLine : { data : [ {type : 'average', name: '平均值'} ] }, 

//绘制最高最低点 markPoint : { data : [ {type : 'max', name: '最大值'}, {type : 'min', name: '最小值'} ] } } ] }, 

//第2个时间点 

//2003年数据表,新增内容 { title:{ text:'2003年货物销量图', subtext:'纯属捏造,如有雷同,人品爆发。' }, series : [ { type:'line', data:[10, 20, 36, 18, 26, 16,20,34], 

//绘制平均线 markLine : { data : [ {type : 'average', name: '平均值'} ] }, 

//绘制最高最低点 markPoint : { data : [ {type : 'max', name: '最大值'}, {type : 'min', name: '最小值'} ] } } ] }, //第3个时间点 {}, //... ] }

联系我们