Vous pouvez travailler avec l'ensemble de données à la fois dans Excel ordinaire et dans le notebook Jupyter, les champs de données sont séparés par des tabulations. Nous nous concentrerons sur la dernière option, et toutes les commandes seront données en tenant compte du fait que le travail est effectué dans un notebook jupyter.
Nous travaillerons sous Windows. Par conséquent, utilisez cmd pour accéder au dossier contenant le jeu de données téléchargé et exécutez jupyter notebook avec la commande du même nom.
Ensuite, importons les modules.
import pandas as pd
import numpy as np
Étant donné que l'ensemble de données ne contient pas d'en-têtes, désignons-les avant de charger l'ensemble de données:
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']
Tout est clair ici: titre de l'article, lien vers celui-ci, identifiant de l'article, note (nombre de plus), date de l'article, nombre de commentaires, identifiant de l'auteur, méta-évaluation de l'article, nom de l'auteur, lien vers l'auteur, lien vers la communauté.
Nous comptons l'ensemble de données.
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)
Voici une légère optimisation des valeurs lues afin que certaines colonnes apparaissent comme numériques.
L'ensemble de données représente donc 468 595 lignes, 11 colonnes.
print(df.shape)#468595 ,11
5 premiers enregistrements
df.head(5)
Description statistique:
df.describe()
Utilisation de valeurs vides dans un ensemble de données
Malgré le fait que les analyseurs ont travaillé sans relâche, il y a de petits trous dans le jeu de données, en d'autres termes, des trous technologiques représentés par des lacunes. Ces lacunes chez les pandas ont la valeur NaN. Voyons le nombre de lignes avec de tels vides:
len(df.loc[pd.isnull( df['story_title'])])
À quoi ça ressemble sur l'ensemble de données:
df.loc[pd.isnull( df['story_title'])]
1444 lignes avec des lacunes ne gâchent pas l'image globale, mais, néanmoins, débarrassons-nous-en:
data1=df.dropna(axis=0, thresh=5)
Nous vérifions que la suppression a réussi:
len(data1.loc[pd.isnull(data1['story_id'])])
Travaillons avec l'ensemble de données
Voyons les noms des colonnes
df.columns
Choisissons la première colonne
col = df['story_title']
col
Jetons un coup d'œil au minimum dans l'ensemble de données
data1.min()
Maximum
data1.max()
La même chose est plus visuelle:
data1.loc[:,['user_name', 'data_rating', 'story_comments']].min()
Maintenant, rassemblons les valeurs des colonnes intéressantes dans un tableau:
arr = data1[['story_id', 'data_rating', 'data_timestamp','user_name']].values
Vous pouvez regarder l'une des colonnes du tableau:
arr[:, 1] #
Regardons le nombre d'articles avec une note de plus de 10000:
print((arr[:, 1] > 10000.0).sum())
Seuls 2672 articles ont une note ultra élevée sur 450k
Dessinons des graphiques
Tout d'abord, importons le module:
import matplotlib.pyplot as plt
Voyons s'il y a un lien entre l'identifiant de l'auteur de l'article et la note de l'article?
plt.scatter(data1['data_author_id'], data1['data_rating'])
plt.xlabel('data_author_id')
plt.ylabel('data_rating')
En raison de la grande quantité de données, il est difficile de saisir la relation et, très probablement, elle est manquante.
Existe-t-il une relation entre l'identifiant de l'article et l'évaluation de l'article?
plt.scatter(data1['story_id'], data1['data_rating'])
plt.xlabel('story_id')
plt.ylabel('data_rating')
Il est à noter ici que les publications avec un nombre plus élevé (publications ultérieures) reçoivent une note plus élevée, elles sont plus souvent votées. La ressource gagne-t-elle en popularité?
Y a-t-il une relation entre la date de l'article et la note?
plt.scatter(data1['data_timestamp'], data1['data_rating'])
plt.xlabel('data_timestamp')
plt.ylabel('data_rating')
Vous pouvez également voir la relation entre les publications ultérieures et le classement des publications. Un meilleur contenu ou, encore une fois, simplement une augmentation du trafic sur le site Web?
Y a-t-il un lien entre la note d'un article et le nombre de commentaires sur celui-ci?
plt.scatter(data1['story_comments'], data1['data_rating'])
plt.xlabel('story_comments')
plt.ylabel('data_rating')
Il existe ici une relation linéaire, bien qu'elle soit très dispersée. Il y a une certaine logique, plus la note du message est élevée, plus il y a de commentaires.
Jetons un coup d'œil aux meilleurs auteurs (auteurs avec les notes totales les plus élevées):
top_users_df = data1.groupby('user_name')[['data_rating']].sum().sort_values('data_rating', ascending=False).head(10)
top_users_df
Ajoutons de la clarté:
top_users_df.style.bar()
Essayons d'autres outils de visualisation. Par exemple 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
Construisons des graphiques en utilisant des colonnes avec l'identifiant de l'article, leur note et leurs commentaires, enregistrez le résultat au format .png:
%config InlineBackend.figure_format = 'png'
sns_plot = sns.pairplot(data1[['story_id', 'data_rating', 'story_comments']]);
sns_plot.savefig('pairplot.png')
Essayons l'outil de visualisation Plotly
from plotly.offline import init_notebook_mode, iplot
import plotly
import plotly.graph_objs as go
init_notebook_mode(connected=True)
Regroupons les données par date et note totale des articles pour cette date:
df2 = data1.groupby('data_timestamp')[['data_rating']].sum()
df2.head()
Voyons combien d'articles ont été publiés à une certaine date (mois):
released_stories = data1.groupby('data_timestamp')[['story_id']].count()
released_stories.head()
Collons deux tableaux:
years_df = df2.join(released_stories)
years_df.head()
Maintenant, dessinons en utilisant 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 beauté de l'intrigue est son interactivité. Dans ce cas, en survol, le graphique montre la note totale des articles pour une certaine date (mois). On constate que la note a baissé en 2020. Mais cela peut s'expliquer par le fait que le nombre d'articles de cet intervalle n'a pas été suffisamment collecté par les analyseurs, et aussi que les posts n'ont pas encore acquis un nombre suffisant de plus.
Au bas du graphique, la ligne rouge indique également de manière interactive le nombre d'articles uniques pour une date spécifique.
Sauvegardons le graphique sous forme de fichier html.
plotly.offline.plot(fig, filename='stats_pikabu.html', show_link=False);
Regroupements de données
Voyons combien d'auteurs se trouvent dans l'ensemble de données:
data1.groupby('user_name').size()
Combien d'articles par auteur:
data1['user_name'].value_counts()
Qui écrit le plus souvent (plus de 500 articles):
for i in data1.groupby('user_name').size():
if i>500:
print (data1.iloc[i,8],i) #8- user_name
C'est donc qui "obstrue" la ressource). Il n'y en a pas tellement:
auteurs
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
Voyons combien de communautés il y a sur la ressource au total:
data1.groupby('story__community_link').size()
Et lequel est le plus prolifique:
data1['story__community_link'].value_counts()
* Les données sur la communauté ne sont pas entièrement correctes, puisque la première communauté mentionnée a été collectée lors de l'analyse, et les auteurs indiquent souvent plusieurs pièces.
Enfin, voyons comment appliquer la fonction avec la sortie du résultat dans une colonne séparée .
Cela sera nécessaire pour une étude plus approfondie de l'ensemble de données.
Fonction simple pour attribuer la note d'un article à un groupe.
Si la note est supérieure à <5000 - mauvais,> 5000 - bon.
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'
Appliquons la fonction ratingGroup au DataFrame et affichons le résultat dans une colonne séparée -ratingGroup
data1['ratingGroup'] = data1.apply( ratingGroup, axis = 1 )
data1.head(10)
Une nouvelle colonne apparaîtra dans l'ensemble de données avec les valeurs suivantes:
Télécharger - ensemble de données .
Téléchargez un ensemble de données non nettoyé pour nettoyer vous - même les doublons - un ensemble de données .
* python nettoie (supprime les lignes en double en fonction de l'identifiant de l'article) pendant près d'une heure! Si quelqu'un réécrit le code en C ++, je vous en serai reconnaissant!:
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 question est supprimée, tk. de manière inattendue) a trouvé un dictionnaire en python qui fonctionne 10 fois plus vite:
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()
Bloc-notes Jupyter - télécharger .