2017-07-06 3 views
3

J'essaie d'apporter des modifications à chaque chaîne de mon objet Series 'tweet_text', mais pour une raison quelconque lorsque j'imprime l'objet série après avoir apporté des modifications aux tweets de ma boucle for, j'obtiens les mêmes chaînes que celles pour la boucle. Comment puis-je réparer cela?Pourquoi mon fichier de données pandas ne met-il pas à jour ses valeurs lorsque je les change?

import pandas as pd 
import re 
import string 

df = pd.read_csv('sample-tweets.csv', 
       names=['Tweet_Date', 'User_ID', 'Tweet_Text', 'Favorites', 'Retweets', 'Tweet_ID']) 

sum_df = df[['User_ID', 'Tweet_ID', 'Tweet_Text']].copy() 
sum_df.set_index(['User_ID']) 
# print sum_df 

tweet_text = df.ix[:, 2] 
print type(tweet_text) 

# efficiency could be im proved by using translate method 
# regex = re.compile('[%s]' % re.escape(string.punctuation)) 

for tweet in tweet_text: 
    tweet = re.sub('https://t.co/[a-zA-Z0-9]*', "", tweet) 
    tweet = re.sub('@[a-zA-Z0-9]*', '', tweet) 
    tweet = re.sub('#[a-zA-Z0-9]*', '', tweet) 
    tweet = re.sub('$[a-zA-Z0-9]*', '', tweet) 
    tweet = ''.join(i for i in tweet if not i.isdigit()) 
    tweet = tweet.replace('"', '') 
    tweet = re.sub(r'[\(\[].*?[\)\]]', '', tweet) # takes out everything between parentheses also, fix this 

    # gets rid of all punctuation and emoji's 
    tweet = "".join(l for l in tweet if l not in string.punctuation) 
    tweet = re.sub(r'[^\x00-\x7F]+',' ', tweet) 

    # gets ride of all extra spacing 
    tweet = tweet.lower() 
    tweet = tweet.strip() 
    tweet = " ".join(tweet.split()) 

    count = count + 1 
    # print tweet 

print tweet_text 
+2

Parce que vous prenez le tweet dans la variable, y apporter des modifications, puis l'itération suivante commence. Vous n'assignez pas les données modifiées à la série. – TrigonaMinima

Répondre

1

Les chaînes Python sont immuables. Vous modifiez simplement la valeur attribuée à la variable tweet, mais jamais réellement la mise à jour de la structure de données.

Il vous suffit de réinsérer la valeur mise à jour dans votre base de données. Exemple d'une solution simple:

for i, tweet in enumerate(tweet_text): 
    tweet = re.sub('https://t.co/[a-zA-Z0-9]*', "", tweet) 
    tweet = re.sub('@[a-zA-Z0-9]*', '', tweet) 

    # ... 

    # update dataframe 
    df.ix[i, 2] = tweet 
+0

Merci! J'ai continué à essayer de voir si les dataframes étaient immuables, mais j'ai oublié de vérifier si les chaînes sont immuables (j'aurais attendu autrement en python haha) – praneeth98

2

Il se passe comme ça parce tweet_text est une copie d'une colonne df.ix[:, 2] pour commencer. Deuxièmement, ce n'est pas une façon de pandas pour itérer Series - vous devez utiliser apply().

Pour mettre à jour votre code, tout ce qui se passe dans la boucle, changer en fonction:

def parse_tweet(tweet): 
    ## everything from loop goes here 
    return tweet 

Puis, au lieu de:

tweet_text = df.ix[:, 2] 

faire:

df.iloc[:, 2] = df.iloc[:, 2].apply(parse_tweet) 

BTW, n'utilisez pas l'indexeur ix car il est déprécié et va être supprimé dans les futures versions de pandas.

+1

En ce qui concerne votre réponse aux pandas les plus récentes. Les gens ne peuvent pas voter sans 15 représentants. Les gens posant les questions sont votre vote le plus certain. Si vous répondez à une question de quelqu'un sans le représentant requis pour vous mettre à votez ... faites-leur une faveur et votez pour leur question afin de les aider à franchir la ligne. – piRSquared

+0

c'est un très bon conseil, le plus apprécié, @piRSquared! – mkos