
Você pode trabalhar com o conjunto de dados no Excel comum e no caderno Jupyter, os campos de dados são separados por guias. Vamos nos concentrar na última opção, e todos os comandos serão dados levando em consideração o fato de que o trabalho está sendo feito em um notebook jupyter.
Vamos trabalhar no windows. Portanto, use cmd para ir para a pasta com o conjunto de dados baixado e execute o jupyter notebook com o comando de mesmo nome.
A seguir, vamos importar os módulos.
import pandas as pd
import numpy as np
Como o conjunto de dados não contém cabeçalhos, vamos designá-los antes de carregar o conjunto de dados:
headers=['story_title','link','story_id','data_rating','data_timestamp','story_comments','data_author_id','data_meta_rating','user_name','user_link','story__community_link']
Tudo está claro aqui: título do artigo, link para ele, id do artigo, classificação (número de sinais de adição), data do artigo, número de comentários, id do autor, meta classificação do artigo, nome do autor, link para o autor, link para a comunidade.
Contamos o conjunto de dados.
df = pd.read_csv('400k-pikabu.csv',parse_dates=['data_timestamp'],
warn_bad_lines=True,
index_col = False,
dtype ={'story_title':'object','link':'object','story_id':'float32','data_rating':'float32',
'story_comments':'float32','data_author_id':'float32'},
delimiter='\t',names=headers)
Aqui está uma pequena otimização dos valores lidos para que algumas colunas apareçam como numéricas.
Portanto, o conjunto de dados representa 468.595 linhas, 11 colunas.
print(df.shape)#468595 ,11
5 primeiros registros
df.head(5)

Descrição estatística:
df.describe()

Trabalhar com valores vazios em um conjunto de dados
Apesar dos parsers trabalharem incansavelmente, existem pequenos furos no conjunto de dados, ou seja, furos tecnológicos representados por lacunas. Essas lacunas nos pandas vêm com o valor NaN. Vamos ver o número de linhas com tais vazios:
len(df.loc[pd.isnull( df['story_title'])])
Como fica no conjunto de dados:
df.loc[pd.isnull( df['story_title'])]

1444 linhas com lacunas não estragam o quadro geral, mas, mesmo assim, vamos nos livrar delas:
data1=df.dropna(axis=0, thresh=5)
Verificamos se a exclusão foi bem-sucedida:
len(data1.loc[pd.isnull(data1['story_id'])])
Vamos trabalhar com o conjunto de dados
Vamos ver os nomes das colunas
df.columns

Vamos selecionar a primeira coluna
col = df['story_title']
col

Vamos dar uma olhada no mínimo no conjunto de dados
data1.min()

Máximo
data1.max()

O mesmo é mais visual:
data1.loc[:,['user_name', 'data_rating', 'story_comments']].min()

Agora vamos coletar os valores das colunas interessantes em uma matriz:
arr = data1[['story_id', 'data_rating', 'data_timestamp','user_name']].values
Você pode olhar para uma das colunas da matriz:
arr[:, 1] #

Vejamos o número de artigos com uma classificação de mais de 10.000:
print((arr[:, 1] > 10000.0).sum())
Apenas 2.672 artigos têm uma classificação ultra-alta de 450k
Vamos desenhar gráficos
Primeiro, vamos importar o módulo:
import matplotlib.pyplot as plt
Vamos descobrir se existe uma conexão entre o id do autor do artigo e a avaliação do artigo?
plt.scatter(data1['data_author_id'], data1['data_rating'])
plt.xlabel('data_author_id')
plt.ylabel('data_rating')

Devido à grande quantidade de dados, é difícil entender a relação e, muito provavelmente, está faltando.
Existe uma relação entre o id do artigo e a avaliação do artigo?
plt.scatter(data1['story_id'], data1['data_rating'])
plt.xlabel('story_id')
plt.ylabel('data_rating')

É perceptível aqui que as postagens com um número maior (postagens posteriores) recebem uma classificação mais elevada, pois são votadas com mais frequência. O recurso está crescendo em popularidade?
Existe alguma relação entre a data do artigo e a avaliação?
plt.scatter(data1['data_timestamp'], data1['data_rating'])
plt.xlabel('data_timestamp')
plt.ylabel('data_rating')

Você também pode ver a relação entre postagens mais recentes e classificações de postagens. Melhor conteúdo ou, novamente, apenas um aumento no tráfego do site?
Existe uma conexão entre a classificação de um artigo e o número de comentários sobre ele?
plt.scatter(data1['story_comments'], data1['data_rating'])
plt.xlabel('story_comments')
plt.ylabel('data_rating')

Existe uma relação linear aqui, embora seja altamente dispersa. Existe uma certa lógica, quanto maior a avaliação da postagem, mais comentários.
Vejamos os principais autores (autores com as maiores avaliações totais):
top_users_df = data1.groupby('user_name')[['data_rating']].sum().sort_values('data_rating', ascending=False).head(10)
top_users_df

Vamos adicionar clareza:
top_users_df.style.bar()

Vamos tentar outras ferramentas de visualização. Por exemplo, nascido do mar
#
! pip3 install seaborn
from __future__ import (absolute_import, division,
print_function, unicode_literals)
#
import warnings
warnings.simplefilter('ignore')
# jupyter'e
%pylab inline
# svg
%config InlineBackend.figure_format = 'svg'
#
from pylab import rcParams
rcParams['figure.figsize'] = 6,3
import seaborn as sns
Vamos construir gráficos usando colunas com id de postagem, suas avaliações e comentários, salve o resultado em .png:
%config InlineBackend.figure_format = 'png'
sns_plot = sns.pairplot(data1[['story_id', 'data_rating', 'story_comments']]);
sns_plot.savefig('pairplot.png')

Vamos tentar a ferramenta de visualização Plotly
from plotly.offline import init_notebook_mode, iplot
import plotly
import plotly.graph_objs as go
init_notebook_mode(connected=True)
Vamos agrupar os dados por data e classificação total de artigos para esta data:
df2 = data1.groupby('data_timestamp')[['data_rating']].sum()
df2.head()

Vamos ver quantos artigos foram publicados em uma determinada data (mês):
released_stories = data1.groupby('data_timestamp')[['story_id']].count()
released_stories.head()

Vamos colar duas tabelas:
years_df = df2.join(released_stories)
years_df.head()

Agora vamos desenhar usando plotly:
trace0 = go.Scatter(
x=years_df.index,
y=years_df.data_rating,
name='data_rating'
)
trace1 = go.Scatter(
x=years_df.index,
y=years_df.story_id,
name='story_id'
)
data = [trace0, trace1]
layout = {'title': 'Statistics'}
fig = go.Figure(data=data, layout=layout)
iplot(fig, show_link=False)

A beleza do enredo é sua interatividade. Neste caso, ao passar o mouse, o gráfico mostra a avaliação total dos artigos para uma determinada data (mês). Percebe-se que a classificação caiu em 2020. Mas isso pode ser explicado pelo fato de o número de artigos desse intervalo não ter sido suficientemente coletado pelos parsers, bem como pelo fato de os posts ainda não terem adquirido um número suficiente de vantagens.
Na parte inferior do gráfico, uma linha vermelha também mostra interativamente o número de artigos exclusivos para uma data específica.
Vamos salvar o gráfico como um arquivo html.
plotly.offline.plot(fig, filename='stats_pikabu.html', show_link=False);
Agrupamentos de dados
Vamos ver quantos autores existem no conjunto de dados:
data1.groupby('user_name').size()

Quantos artigos por autor:
data1['user_name'].value_counts()

Quem escreve com mais frequência (mais de 500 artigos):
for i in data1.groupby('user_name').size():
if i>500:
print (data1.iloc[i,8],i) #8- user_name
Então é isso que "entope" o recurso). Não há tantos deles:
autores
crackcraft 531
mpazzz 568
kastamurzik 589
pbdsu 773
RedCatBlackFox 4882
Wishhnya 1412
haalward 1190
iProcione 690
tooNormal 651
Drugayakuhnya 566
Ozzyab 1088
kalinkaElena9 711
Freshik04 665
100pudofff 905
100pudofff 1251
Elvina.Brestel 1533
1570525 543
Samorodok 597
Mr.Kolyma 592
kka2012 505
DENTAARIUM 963
4nat1k 600
chaserLI 650
kostas26 1192
portal13 895
exJustice 1477
alc19 525
kuchka70 572
SovietPosters 781
Grand.Bro 1051
Rogo3in 1068
fylhtq2222 774
deystvitelno 539
lilo26 802
al56.81 2498
Hebrew01 596
TheRovsh 803
ToBapuLLI 1143
ragnarok777 893
Ichizon 890
hoks1 610
arthik 700
mpazzz 568
kastamurzik 589
pbdsu 773
RedCatBlackFox 4882
Wishhnya 1412
haalward 1190
iProcione 690
tooNormal 651
Drugayakuhnya 566
Ozzyab 1088
kalinkaElena9 711
Freshik04 665
100pudofff 905
100pudofff 1251
Elvina.Brestel 1533
1570525 543
Samorodok 597
Mr.Kolyma 592
kka2012 505
DENTAARIUM 963
4nat1k 600
chaserLI 650
kostas26 1192
portal13 895
exJustice 1477
alc19 525
kuchka70 572
SovietPosters 781
Grand.Bro 1051
Rogo3in 1068
fylhtq2222 774
deystvitelno 539
lilo26 802
al56.81 2498
Hebrew01 596
TheRovsh 803
ToBapuLLI 1143
ragnarok777 893
Ichizon 890
hoks1 610
arthik 700
Vamos ver quantas comunidades existem no recurso no total:
data1.groupby('story__community_link').size()

E qual é o mais prolífico:
data1['story__community_link'].value_counts()

* Os dados sobre a comunidade não estão totalmente corretos, visto que a primeira comunidade mencionada foi coletada durante a análise e os autores frequentemente indicam várias peças.
Finalmente, vamos ver como aplicar a função com a saída do resultado em uma coluna separada .
Isso será necessário para um estudo mais aprofundado do conjunto de dados.
Uma função simples para atribuir a classificação de um artigo a um grupo.
Se a classificação for superior a <5000 - ruim,> 5000 - bom.
def ratingGroup( row ):
# , NaN
if not pd.isnull( row['data_rating'] ):
if row['data_rating'] <= 5000:
return 'bad'
if row['data_rating'] >= 20000:
return 'good'
# NaN, Undef
return 'Undef'
Vamos aplicar a função ratingGroup ao DataFrame e exibir o resultado em uma coluna separada -ratingGroup
data1['ratingGroup'] = data1.apply( ratingGroup, axis = 1 )
data1.head(10)
Uma nova coluna aparecerá no conjunto de dados com os seguintes valores:

Download - conjunto de dados .
Baixe um conjunto de dados não limpo para limpar você mesmo as duplicatas - um conjunto de dados .
* python limpa (remove linhas duplicadas com base no id do artigo) por quase uma hora! Se alguém reescrever o código em C ++, ficarei grato!:
with open('f-final-clean-.txt','a',encoding='utf8',newline='') as f:
for line in my_lines:
try:
b=line.split("\t")[2]
if b in a:
pass
else:
a.append(b)
f.write(line)
except:
print(line)
A questão foi removida, tk. inesperadamente) encontrou um dicionário em python que funciona 10 vezes mais rápido:
a={}
f = open("f-final.txt",'r',encoding='utf8',newline='')
f1 = open("f-final-.txt",'a',encoding='utf8',newline='')
for line in f.readlines():
try:
b=line.split("\t")[2]
if b in a:
pass
else:
a[b]=b
#print (a[b])
f1.write(line)
except:
pass
f.close()
f1.close()
Caderno Jupyter - download .