使用列中的列表整理DataFrame的最佳方法

时间:2018-03-15 04:28:10

标签: python python-3.x pandas dataframe scikit-learn

我有一个不整齐的Tweet对象DataFrame。有两列包含列表:hashtagsexpanded_urls。我试图通过在行/列索引中仅保留1个值来遵循整洁的数据原则。

编辑:此问题被标记为this answer的副本,只是将列表拆分为更多列。这对我不起作用,因为1条推文中可能存在可变数量的主题标签。

以下是我的tweet DataFrame的示例:

-----------------------------------------------------------
tweet_id | hashtags       | expanded_urls
-----------------------------------------------------------
  123    | ['lol','bff']  | ['fakeurl.com']
  124    | []             | ['url1.io', 'url2.expanded.co']

我可以通过两种方式来整理这些数据。

1:只需向DataFrame添加新行,几乎所有行内容都已复制

---------------------------------------------
tweet_id | hashtag   | expanded_url
---------------------------------------------
  123    | 'lol'    | 'fakeurl.com'
  123    | 'bff'    | 'fakeurl.com'
  124    | ''       | 'url1.io'
  124    | ''       | 'url2.expanded.io'

我不认为这会非常有效,特别是因为会有很多插入/追加操作。但是,将单个DataFrame传递到单个scikit-learn模型会使事情变得非常简单。

2:创建2个新的DataFrames:

第一个是带有相应tweet_id s的主题标签:

------------------
tweet_id | hashtag
------------------
123      | `lol`
123      | `bff`

另一个是带有相应tweet_id s的网址:

------------------
tweet_id | url
------------------
123      | `fakeurl.com`
124      | `url1.io`
124      | `url2.expanded.co`

这看起来更干净,但我不完全确定如何修改原始DataFrame;我会删除相应的列并保留3个单独的表吗?有没有一种很好的方法可以将这3个DataFrame合并为1,或者每次我想知道哪些主题标签与推文相关时,我是否必须单独查找?

2 个答案:

答案 0 :(得分:2)

我重新分配df以将空列表转换为单个空字符串的列表

两列一起

from itertools import product

df = df.applymap(lambda x: x if x else [''])

pd.DataFrame([
    [t, h, e]
    for t, h_, e_ in df.values
    for h, e in product(h_, e_)
], columns=df.columns)

   tweet_id hashtags     expanded_urls
0       123      lol       fakeurl.com
1       123      bff       fakeurl.com
2       124                    url1.io
3       124           url2.expanded.co

或没有itertools

df = df.applymap(lambda x: x if x else [''])

pd.DataFrame([
    [t, h, e]
    for t, h_, e_ in df.values
    for h in h_ for e in e_
], columns=df.columns)

   tweet_id hashtags     expanded_urls
0       123      lol       fakeurl.com
1       123      bff       fakeurl.com
2       124                    url1.io
3       124           url2.expanded.co

单独

pd.DataFrame(dict(
    tweet_id=df.tweet_id.values.repeat(df.hashtags.str.len()),
    hashtags=np.concatenate(df.hashtags.values)
), columns=['tweet_id', 'hashtags'])

   tweet_id hashtags
0       123      lol
1       123      bff
pd.DataFrame(dict(
    tweet_id=df.tweet_id.values.repeat(df.expanded_urls.str.len()),
    expanded_urls=np.concatenate(df.expanded_urls.values)
), columns=['tweet_id', 'expanded_urls'])

   tweet_id     expanded_urls
0       123       fakeurl.com
1       124           url1.io
2       124  url2.expanded.co

答案 1 :(得分:1)

假设索引在tweet_id上(,如果没有.set_index()方法),对于方法2,您可以尝试:

df['hashtags'].apply(pd.Series).stack().reset_index(level=1, drop=True).to_frame('hashtag')

Result:
               hashtag
tweet_id             
123               lol
123               bff

同样适用于expanded_urls

df['expanded_urls'].apply(pd.Series).stack().reset_index(level=1, drop=True).to_frame('url')

结果:

                  url
tweet_id                  
123            fakeurl.com
124                url1.io
124       url2.expanded.co