Puede trabajar con un conjunto de datos tanto en Excel normal como en Jupyter Notebook, los campos de datos están separados por pestañas. Nos centraremos en la última opción, y todos los comandos se darán teniendo en cuenta que se está trabajando en un cuaderno jupyter.
Trabajaremos en windows. Por lo tanto, use cmd para ir a la carpeta con el conjunto de datos descargado y ejecute jupyter notebook con el comando del mismo nombre.
A continuación, importemos los módulos.
import pandas as pd
import numpy as np
Dado que el conjunto de datos no contiene encabezados, designémoslos antes de cargar el conjunto de datos:
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']
Todo está claro aquí: título del artículo, enlace al mismo, identificación del artículo, calificación (número de ventajas), fecha del artículo, número de comentarios, identificación del autor, meta calificación del artículo, nombre del autor, enlace al autor, enlace a la comunidad.
Contamos el conjunto de datos.
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)
A continuación, presentamos una ligera optimización de los valores leídos para que algunas columnas aparezcan como numéricas.
Entonces, el conjunto de datos representa 468,595 filas, 11 columnas.
print(df.shape)#468595 ,11
Primeros 5 registros
df.head(5)
Descripción estadística:
df.describe()
Trabajar con valores vacíos en un conjunto de datos
A pesar de que los analizadores trabajaron incansablemente, hay pequeños agujeros en el conjunto de datos, en otras palabras, agujeros tecnológicos representados por vacíos. Estos huecos en pandas vienen con el valor NaN. Veamos la cantidad de líneas con tales vacíos:
len(df.loc[pd.isnull( df['story_title'])])
Cómo se ve en el conjunto de datos:
df.loc[pd.isnull( df['story_title'])]
1444 líneas con espacios no estropean el panorama general, pero, sin embargo, eliminémoslas:
data1=df.dropna(axis=0, thresh=5)
Verificamos que la eliminación fue exitosa:
len(data1.loc[pd.isnull(data1['story_id'])])
Trabajemos con el conjunto de datos
Veamos los nombres de las columnas.
df.columns
Seleccionemos la primera columna
col = df['story_title']
col
Echemos un vistazo al mínimo en el conjunto de datos.
data1.min()
Máximo
data1.max()
Lo mismo es más descriptivo:
data1.loc[:,['user_name', 'data_rating', 'story_comments']].min()
Ahora recopilemos los valores de las columnas interesantes en una matriz:
arr = data1[['story_id', 'data_rating', 'data_timestamp','user_name']].values
Puede mirar una de las columnas de la matriz:
arr[:, 1] #
Veamos la cantidad de artículos con una calificación de más de 10,000:
print((arr[:, 1] > 10000.0).sum())
Solo 2672 artículos tienen una calificación ultra alta de 450k
Dibujemos gráficos
Primero, importemos el módulo:
import matplotlib.pyplot as plt
Averigüemos si existe una conexión entre la identificación del autor del artículo y la calificación del artículo.
plt.scatter(data1['data_author_id'], data1['data_rating'])
plt.xlabel('data_author_id')
plt.ylabel('data_rating')
Debido a la gran cantidad de datos, es difícil comprender la relación y, muy probablemente, faltan.
¿Existe una relación entre la identificación del artículo y la calificación del artículo?
plt.scatter(data1['story_id'], data1['data_rating'])
plt.xlabel('story_id')
plt.ylabel('data_rating')
Aquí se nota que las publicaciones con un número más alto (publicaciones posteriores) reciben una calificación más alta, son más votadas ¿Está ganando popularidad el recurso?
¿Existe una relación entre la fecha del artículo y la calificación?
plt.scatter(data1['data_timestamp'], data1['data_rating'])
plt.xlabel('data_timestamp')
plt.ylabel('data_rating')
También puede ver la relación entre publicaciones más recientes y clasificaciones de publicaciones. ¿Mejor contenido o, nuevamente, solo un aumento en el tráfico del sitio web?
¿Existe una conexión entre la calificación de un artículo y la cantidad de comentarios?
plt.scatter(data1['story_comments'], data1['data_rating'])
plt.xlabel('story_comments')
plt.ylabel('data_rating')
Aquí hay una relación lineal, aunque muy dispersa. Existe una cierta lógica, cuanto mayor es la calificación de la publicación, más comentarios.
Echemos un vistazo a los principales autores (autores con las calificaciones totales más altas de publicaciones):
top_users_df = data1.groupby('user_name')[['data_rating']].sum().sort_values('data_rating', ascending=False).head(10)
top_users_df
Agreguemos claridad:
top_users_df.style.bar()
Probemos otras herramientas de visualización. Por ejemplo seaborn
#
! 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
Construyamos gráficos usando columnas con ID de publicación, su calificación y comentarios, guarde el resultado en .png:
%config InlineBackend.figure_format = 'png'
sns_plot = sns.pairplot(data1[['story_id', 'data_rating', 'story_comments']]);
sns_plot.savefig('pairplot.png')
Probemos la herramienta de visualización Plotly
from plotly.offline import init_notebook_mode, iplot
import plotly
import plotly.graph_objs as go
init_notebook_mode(connected=True)
Agrupemos los datos por fecha y calificación total de artículos para esta fecha:
df2 = data1.groupby('data_timestamp')[['data_rating']].sum()
df2.head()
Veamos cuántos artículos se publicaron en una fecha determinada (mes):
released_stories = data1.groupby('data_timestamp')[['story_id']].count()
released_stories.head()
Peguemos dos tablas:
years_df = df2.join(released_stories)
years_df.head()
Ahora dibujemos 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)
La belleza de la trama es su interactividad. En este caso, al pasar el mouse, el gráfico muestra la calificación total de los artículos para una fecha determinada (mes). Se puede ver que la calificación bajó en 2020. Pero esto se puede explicar por el hecho de que los analizadores no han recopilado suficientemente la cantidad de artículos de este intervalo, así como por el hecho de que las publicaciones aún no han adquirido un número suficiente de ventajas.
En la parte inferior del gráfico, la línea roja también muestra de forma interactiva el número de artículos únicos para una fecha específica.
Guardemos el gráfico como un archivo html.
plotly.offline.plot(fig, filename='stats_pikabu.html', show_link=False);
Agrupaciones de datos
Veamos cuántos autores hay en el conjunto de datos:
data1.groupby('user_name').size()
Cuántos artículos por autor:
data1['user_name'].value_counts()
Quién escribe con más frecuencia (más de 500 artículos):
for i in data1.groupby('user_name').size():
if i>500:
print (data1.iloc[i,8],i) #8- user_name
Entonces es quien "obstruye" el recurso). No hay tantos:
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
Veamos cuántas comunidades hay en el recurso en total:
data1.groupby('story__community_link').size()
Y cuál es el más prolífico:
data1['story__community_link'].value_counts()
* Los datos sobre la comunidad no son del todo correctos, ya que la primera comunidad mencionada se recopiló durante el análisis y los autores suelen indicar varias piezas.
Finalmente, veamos cómo aplicar la función con la salida del resultado en una columna separada .
Esto será necesario para un estudio más detallado del conjunto de datos.
Una función simple para asignar la calificación de un artículo a un grupo.
Si la calificación es más de <5000 - mala,> 5000 - buena.
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'
Apliquemos la función ratingGroup al DataFrame y mostremos el resultado en una columna separada -ratingGroup
data1['ratingGroup'] = data1.apply( ratingGroup, axis = 1 )
data1.head(10)
Aparecerá una nueva columna en el conjunto de datos con los siguientes valores:
Descargar - conjunto de datos .
Descargue un conjunto de datos sin limpiar para limpiar usted mismo los duplicados: un conjunto de datos .
* Python limpia (elimina las líneas duplicadas según la identificación del artículo) durante casi una hora. Si alguien reescribe el código en C ++, ¡estaré agradecido!:
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)
La pregunta está despejada, porque inesperadamente) encontré un diccionario en Python que funciona 10 veces más 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()
Jupyter notebook - descargar .