Spotify en Python Parte 1: Preprocesamiento
En este artículo, comenzaremos a introducir sus datos de Spotify en Python. Este será el primer artículo de una serie de artículos sobre Spotify en Python.
En este artículo, voy a:
- Mostrarle cómo obtener sus datos de Spotify en Python.
- Cargue su lista de reproducción de canciones guardadas en un marco de datos.
- Obtenga las funciones de audio de todas sus canciones guardadas.
- Agregue un género (grupo) a cada canción.
- Dé una pequeña conclusión y hable sobre los próximos pasos.
Para empezar, se necesitan las credenciales de usuario de la API de Spotify.
Para hacer esto, deberá seguir estos pasos:
- Vaya al panel de desarrolladores de Spotify (https://developer.spotify.com/dashboard/applications) e inicia sesión con tu cuenta de Spotify.
- Haga clic en el botón "Crear una aplicación" para crear una nueva aplicación de Spotify.
- Complete la información requerida para su aplicación, como el nombre, la descripción y el sitio web. Puede configurar el campo "Redirigir URI" a la URL que desea usar como URL de redirección.
- Después de crear la aplicación, se le proporcionarán los valores "Client ID" y "Client Secret".
- Asegúrese de configurar también las "URI de redirección" en su aplicación de Spotify para que coincidan con la URL de "REDIRECTORIO" que proporcionó .
Guardé las credenciales de la siguiente manera en el archivo “credenciales”:
USUARIO = '…'
CID = '…'
SECRETO = '…'
REDIRECTO = '…'
En un cuaderno de Júpiter, se puede ejecutar el siguiente código para crear un token de usuario usando las credenciales:
#importing libraries
import credentials
import spotipy
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Retrieve user credentials from separate file
user = credentials.USER
cid = credentials.CID
secret = credentials.SECRET
redirect_uri = credentials.REDIRECT
# Define scope of access
scope = 'user-library-read' # user-library-read, user-read-recently-played
# Prompt for user token using credentials
token = spotipy.util.prompt_for_user_token(user, scope, client_id=cid, client_secret=secret, redirect_uri=redirect_uri)
# Create Spotify token and check if successful
if token:
sp = spotipy.Spotify(auth=token)
print('Token created for', user)
else:
print("Can't get token for", user)
# User data
user_data = sp.current_user()
print('My data:')
print('Name:', user_data['display_name'])
print('Followers:', user_data['followers']['total'])
print('Link:', user_data['external_urls']['spotify'])
Derivación de canciones guardadas de la biblioteca de Spotify
En el siguiente código, las canciones guardadas se recuperan de la biblioteca de Spotify. Las canciones se almacenan en un marco de datos de pandas.
# Function to get all saved tracks
def get_saved_tracks():
results = sp.current_user_saved_tracks()
tracks = []
while results['next']:
tracks.extend(results['items'])
results = sp.next(results)
return tracks
# Converting tracks to dataframe
def deconstruct_tracks(tracks):
saved_tracks = []
for track in tracks:
saved_track = {
'added_at': track['added_at'],
'id': track['track']['id'],
'name': track['track']['name'],
'popularity': track['track']['popularity'],
'uri': track['track']['uri'],
'artist': track['track']['artists'][0]['name'],
'album': track['track']['album']['name'],
'release_date': track['track']['album']['release_date'],
'duration_ms': track['track']['duration_ms']
}
saved_tracks.append(saved_track)
return pd.DataFrame(saved_tracks)
tracks_called = get_saved_tracks()
tracklist = deconstruct_tracks(tracks_called)
#%%
tracklist.head(10)
Cargando características de audio
Para hacer un análisis exploratorio de sus canciones guardadas en Spotify, primero es necesario derivar algunas características de las canciones. Las características que se derivarán son:
Acústica : un valor de 0,0 a 1,0 que indica si una pista es acústica, donde 1,0 representa una alta confianza en la naturaleza acústica.
Bailabilidad : una medida de 0,0 a 1,0 que describe qué tan adecuada es una pista para bailar en función de elementos como el tempo, la estabilidad del ritmo, la fuerza del ritmo y la regularidad, siendo 0,0 el menos bailable y 1,0 el más bailable.
Energía : un valor de 0,0 a 1,0 que representa la intensidad y la actividad de una pista, con pistas energéticas que se sienten rápidas, fuertes y ruidosas. Las características perceptivas como el rango dinámico, el volumen percibido, el timbre, la velocidad de inicio y la entropía contribuyen a este atributo.
Instrumentalidad : una predicción de si una pista contiene voces, con valores más cercanos a 1.0 que indican una mayor probabilidad de que no haya contenido vocal. Los valores superiores a 0,5 suelen representar pistas instrumentales, con mayor confianza a medida que el valor se acerca a 1,0.
Liveness : un valor que indica la presencia de una audiencia en una grabación, con valores más altos que representan una mayor probabilidad de una actuación en vivo. Un valor por encima de 0,8 sugiere una gran probabilidad de una pista en vivo.
Sonoridad : la sonoridad general de una pista en decibelios (dB), promediada en toda la pista y útil para comparar la sonoridad relativa de las pistas. Los valores suelen oscilar entre -60 y 0 dB.
Speechiness : una medida que indica la presencia de palabras habladas en una pista, con valores más cercanos a 1.0 que sugieren grabaciones más parecidas al habla. Los valores por encima de 0,66 describen pistas compuestas íntegramente de palabras habladas, mientras que los valores entre 0,33 y 0,66 pueden indicar una mezcla de música y habla, incluida la música rap. Los valores por debajo de 0,33 representan principalmente música y pistas que no son de voz.
Tempo : el tempo general estimado de una pista en pulsaciones por minuto (BPM), que indica la velocidad o el ritmo de la música.
Compás : Término musical que especifica el número de tiempos en cada compás o compás.
Valencia : un valor de 0,0 a 1,0 que describe la positividad musical que transmite una pista, con una valencia alta que indica emociones más positivas como la felicidad y una valencia baja que indica emociones más negativas como la tristeza.
Modo : Un indicador de la modalidad (mayor o menor) de una pista, con 1 representando mayor y 0 representando menor.
Clave : la clave general estimada de una pista, asignada a números enteros mediante la notación de clase de tono estándar (p. ej., 0 = C, 1 = C♯/D♭, 2 = D, etc.).
Utilice el siguiente código para derivar todas estas características.
# Function to get all audio features of the saved tracks
def get_track_features(id):
metadata = sp.track(id)
features = sp.audio_features(id)
# metadata
id = metadata['id']
name = metadata['name']
album = metadata['album']['name']
artist = metadata['album']['artists'][0]['name']
release_date = metadata['album']['release_date']
length = metadata['duration_ms']
popularity = metadata['popularity']
# audio features
acousticness = features[0]['acousticness']
danceability = features[0]['danceability']
energy = features[0]['energy']
instrumentalness = features[0]['instrumentalness']
liveness = features[0]['liveness']
loudness = features[0]['loudness']
speechiness = features[0]['speechiness']
tempo = features[0]['tempo']
time_signature = features[0]['time_signature']
valence = features[0]['valence']
mode = features[0]['mode']
key = features[0]['key']
track = [name, album, artist, release_date, length, popularity, danceability, acousticness, danceability, energy,
instrumentalness, liveness, loudness, speechiness, tempo, time_signature, valence, mode, key]
return track
print("Function defined")
# Loop through each track id and get the tracks features
for i in range(len(tracklist)):
try:
track = get_track_features(tracklist['id'][i])
tracklist.loc[i, 'name'] = track[0]
tracklist.loc[i, 'album'] = track[1]
tracklist.loc[i, 'artist'] = track[2]
tracklist.loc[i, 'release_date'] = track[3]
tracklist.loc[i, 'length'] = track[4]
tracklist.loc[i, 'popularity'] = track[5]
tracklist.loc[i, 'danceability'] = track[6]
tracklist.loc[i, 'acousticness'] = track[7]
tracklist.loc[i, 'danceability'] = track[8]
tracklist.loc[i, 'energy'] = track[9]
tracklist.loc[i, 'instrumentalness'] = track[10]
tracklist.loc[i, 'liveness'] = track[11]
tracklist.loc[i, 'loudness'] = track[12]
tracklist.loc[i, 'speechiness'] = track[13]
tracklist.loc[i, 'tempo'] = track[14]
tracklist.loc[i, 'time_signature'] = track[15]
tracklist.loc[i, 'valence'] = track[16]
tracklist.loc[i, 'mode'] = track[17]
tracklist.loc[i, 'key'] = track[18]
# Save to df
tracklist.to_csv('tracklist.csv', index=False, encoding='utf-8')
except:
print(f"Error with track {i}")
pass
print(f"Features of {len(tracklist)} tracks extracted and saved to tracklist.csv")
Recibí un error para una canción, ya que no era realmente una canción, sino una mezcla de 2 horas de Kerri Chandler. Por supuesto, no es posible derivar un valor para todas estas características de audio. Por lo tanto, esta 'canción' no se lleva a la siguiente etapa de procesamiento.
Género
La API de Spotify no proporciona ningún género con las canciones. Esto es algo que tenemos que solucionar. Podemos hacer esto usando la API, que puede obtener los géneros asociados de cada artista y agregarlos a cada canción.
# Add all genres of the artists to the dataframe
genres = []
for i in range(len(data)):
artist = data['artist'][i]
artist_id = sp.search(artist, type='artist')['artists']['items'][0]['id']
artist_genres = sp.artist(artist_id)['genres']
genres.append(artist_genres)
data['genres'] = genres
data.head(10)
# Transform the genre column to extract specific genres
data['genres'] = data['genres'].astype(str)
data['genres'] = data['genres'].str.replace('[', '')
data['genres'] = data['genres'].str.replace(']', '')
data['genres'] = data['genres'].str.replace("'", '')
data['genres'] = data['genres'].str.replace('"', '')
data.head(10)
# Search for predefined genres in the genre column
strings = ['pop', 'techno', 'house', 'disco', 'electronic',
'trance', 'hip hop', 'rap', 'r&b', 'soul', 'rock',
'metal', 'punk', 'jazz', 'blues', 'country', 'folk',
'reggae', 'classical', 'indie', 'funk']
for string in strings:
data.loc[data['genres'].str.contains(string), 'genre_group'] = string
data.head(10)
Cuenta para cada género:
# Check how many tracks are in each genre group
data['genre_group'].value_counts()
# Count missing values
data['genre_group'].isnull().sum()
print(f"{data['genre_group'].isnull().sum()} tracks are missing a genre group")
# visualize the distribution of the genres
plt.figure(figsize=(15, 10))
sns.countplot(y='genre_group', data=data, order=data['genre_group'].value_counts().index)
for i, genre in enumerate(data['genre_group'].value_counts().index):
count = data['genre_group'].value_counts()[genre]
plt.text(count + 10, i, f'{count}', ha='left', va='center', color='black')
plt.title('Distribution of genres with counts')
plt.show()
Se puede ver que a menudo estoy de humor Funky y Housy, mientras escucho algo de Indie, Disco y Soul.
Nota: a 291 pistas les falta un género (grupo). Este es un problema que abordaremos en la Parte 2 de esta serie.
Próximos pasos
Guarde este marco de datos en un archivo CSV:
data.to_csv('tracklist.csv', index=False, encoding='utf-8')
En los próximos artículos, voy a:
- Haz un análisis exploratorio de datos.
- Mostrar cómo asignar géneros a las canciones que no los tienen.
- Crea listas de reproducción de tus canciones guardadas donde tu música se ordena automáticamente usando Machine Learning.
- Automatice este proceso.
El cuaderno está disponible en mi GitHub:
Muchas gracias a Nils Jennissen y Gabriel Ronnó con quienes trabajé en este proyecto. Asegúrate de seguirlo en su Medium y GitHub:
- https://medium.com/@nilsjennissen
- https://github.com/nilsjenn
- https://medium.com/@gabriel_renno
- https://github.com/GabrielRenno
La maravillosa ilustración está hecha por Kateryna Malachkova. ¡Asegúrate de ver su Medium e Instagram!
- https://medium.com/@malachkovak
- https://instagram.com/ph_malachkova?igshid=ZjE2NGZiNDQ=
- https://github.com/rubentak
- https://www.linkedin.com/in/ruben-tak-665b66194/

![¿Qué es una lista vinculada, de todos modos? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































