GVKun编程网logo

从Pandas Dataframe单元格中将嵌套数组值拆分为多行(pandas dataframe 按列合并)

16

此处将为大家介绍关于从PandasDataframe单元格中将嵌套数组值拆分为多行的详细内容,并且为您解答有关pandasdataframe按列合并的相关问题,此外,我们还将为您介绍关于DaskDat

此处将为大家介绍关于从Pandas Dataframe单元格中将嵌套数组值拆分为多行的详细内容,并且为您解答有关pandas dataframe 按列合并的相关问题,此外,我们还将为您介绍关于Dask Dataframe将列表的列拆分为多列、Pandas Dataframe将具有dict值的列拆分为列 输出、Pandas Dataframe:将列拆分为多列,右对齐不一致的单元格条目、Pandas 将列中的字符串值拆分为多行的有用信息。

本文目录一览:

从Pandas Dataframe单元格中将嵌套数组值拆分为多行(pandas dataframe 按列合并)

从Pandas Dataframe单元格中将嵌套数组值拆分为多行(pandas dataframe 按列合并)

我有以下形式的Pandas DataFrame

在此处输入图片说明

每年每个ID(2008年-2015年)有一行。对于列Max TempMinTemp以及Rain每个单元包含对应于一天在这一年,即对于上述的帧值的阵列

  • frame3.iloc[0][''Max Temp''][0] 是2011年1月1日的值
  • frame3.iloc[0][''Max Temp''][364] 是2011年12月31日的值。

我知道这结构不好,但这是我必须处理的数据。它以这种方式存储在MongoDB中(这些行之一等同于Mongo中的文档)。

我想拆分这些嵌套的数组,以便每年每个ID而不是每个ID排一行。但是,在拆分数组时,我还要基于当前数组索引创建一个新列以捕获一年中的某天。然后,我将使用这一天以及该Year列来创建DatetimeIndex

在此处输入图片说明

答案1

小编典典

您可以.apply(pd.Series)为每个列运行,然后stack合并结果。

对于系列

s = pd.Series([[0, 1], [2, 3, 4]], index=[2011, 2012])sOut[103]: 2011       [0, 1]2012    [2, 3, 4]dtype: object

它的工作原理如下

s.apply(pd.Series).stack()Out[104]: 2011  0    0.0      1    1.02012  0    2.0      1    3.0      2    4.0dtype: float64

该系列的内容长短不一(这很重要,因为2012年是a年)。中间系列(即before stack)的NaN值后来被删除。

现在,让我们来做一个框架:

a = list(range(14))b = list(range(20, 34))df = pd.DataFrame({''ID'': [11111, 11111, 11112, 11112],                   ''Year'': [2011, 2012, 2011, 2012],                   ''A'': [a[:3], a[3:7], a[7:10], a[10:14]],                   ''B'': [b[:3], b[3:7], b[7:10], b[10:14]]})dfOut[108]:                   A                 B     ID  Year0         [0, 1, 2]      [20, 21, 22]  11111  20111      [3, 4, 5, 6]  [23, 24, 25, 26]  11111  20122         [7, 8, 9]      [27, 28, 29]  11112  20113  [10, 11, 12, 13]  [30, 31, 32, 33]  11112  2012

然后我们可以运行:

# set an index (each column will inherit it)df2 = df.set_index([''ID'', ''Year''])# the trickunnested_lst = []for col in df2.columns:    unnested_lst.append(df2[col].apply(pd.Series).stack())result = pd.concat(unnested_lst, axis=1, keys=df2.columns)

并获得:

resultOut[115]:                  A     BID    Year              11111 2011 0   0.0  20.0           1   1.0  21.0           2   2.0  22.0      2012 0   3.0  23.0           1   4.0  24.0           2   5.0  25.0           3   6.0  26.011112 2011 0   7.0  27.0           1   8.0  28.0           2   9.0  29.0      2012 0  10.0  30.0           1  11.0  31.0           2  12.0  32.0           3  13.0  33.0

其余的(日期时间索引)则不太直接。例如:

# DatetimeIndexyears = pd.to_datetime(result.index.get_level_values(1).astype(str))# TimedeltaIndexdays = pd.to_timedelta(result.index.get_level_values(2), unit=''D'')# If the above line doesn''t work (a bug in pandas), try this:# days = result.index.get_level_values(2).astype(''timedelta64[D]'')# the sum is again a DatetimeIndexdates = years + daysdates.name = ''Date''new_index = pd.MultiIndex.from_arrays([result.index.get_level_values(0), dates])result.index = new_indexresultOut[130]:                      A     BID    Date                  11111 2011-01-01   0.0  20.0      2011-01-02   1.0  21.0      2011-01-03   2.0  22.0      2012-01-01   3.0  23.0      2012-01-02   4.0  24.0      2012-01-03   5.0  25.0      2012-01-04   6.0  26.011112 2011-01-01   7.0  27.0      2011-01-02   8.0  28.0      2011-01-03   9.0  29.0      2012-01-01  10.0  30.0      2012-01-02  11.0  31.0      2012-01-03  12.0  32.0      2012-01-04  13.0  33.0

Dask Dataframe将列表的列拆分为多列

Dask Dataframe将列表的列拆分为多列

使用Pandas可以轻松完成相同的任务

import pandas as pddf = pd.DataFrame({"lists":[[i, i+1] for i in range(10)]})df[[''left'',''right'']] = pd.DataFrame([x for x in df.lists])

但是我不知道如何用 dask.dataframe

更新资料

到目前为止,我已经找到了解决方法

ddf = dd.from_pandas(df, npartitions=2)ddf["left"] = ddf.apply(lambda x: x["lists"][0], axis=1, meta=pd.Series())ddf["right"] = ddf.apply(lambda x: x["lists"][1], axis=1, meta=pd.Series())

我想知道是否还有另一种前进的方式。

答案1

小编典典

您可以使用assign以下方法实现此目的:

ddf = ddf.assign(left=ddf.lists.map(lambda x: x[0]),                 right=ddf.lists.map(lambda x: x[1]))

例如,

ddf.compute()     lists  left  right0   [0, 1]     0      11   [1, 2]     1      22   [2, 3]     2      33   [3, 4]     3      44   [4, 5]     4      55   [5, 6]     5      66   [6, 7]     6      77   [7, 8]     7      88   [8, 9]     8      99  [9, 10]     9     10

措辞的另一种方式(请参见下面的评论)可能是

ddf = ddf.assign(**{k: ddf.lists.map(lambda x, i=i: x[i])                  for i, k in enumerate([''left'', ''right''])})

Pandas Dataframe将具有dict值的列拆分为列 输出

Pandas Dataframe将具有dict值的列拆分为列 输出

  • json_normalize不适用于NaN的列
    • NaN填充{}
  • 另请参阅How to json_normalize a column with NaNs?
#  explode the list
df = df.explode('freshness_grades').reset_index(drop=True)

# now fill the NaN with an empty dict
df.freshness_grades = df.freshness_grades.fillna({i: {} for i in df.index})

# then normalize the column
df = df.join(pd.json_normalize(df.freshness_grades))

# drop the column
df.drop(columns=['freshness_grades'],inplace=True)

输出

                        _id                     creation_date                   end_date grade                 start_date
0  57ea8d0d9c624c035f96f45e  2019-04-20T06:02:02.865000+00:00  2015-07-23T18:43:00+00:00     A  2015-03-05T01:54:47+00:00
1  57ea8d0d9c624c035f96f45e  2019-04-20T06:02:02.865000+00:00  2015-08-22T18:43:00+00:00     B  2015-07-23T18:43:00+00:00
2  57ea8d0d9c624c035f96f45e  2019-04-20T06:02:02.865000+00:00  2015-10-21T18:43:00+00:00     C  2015-08-22T18:43:00+00:00
3  57ea8d0d9c624c035f96f45e  2019-04-20T06:02:02.865000+00:00  2016-02-02T12:12:00+00:00     D  2015-10-21T18:43:00+00:00
4  57ea8d0d9c624c035f96f45e  2019-04-20T06:02:02.865000+00:00  2016-07-22T18:43:00+00:00     E  2016-02-02T12:12:00+00:00

Pandas Dataframe:将列拆分为多列,右对齐不一致的单元格条目

Pandas Dataframe:将列拆分为多列,右对齐不一致的单元格条目

我有一个熊猫数据框,其中有一列名为“城市,州,国家/地区”。我想将此列分为三个新列:“城市”,“州”和“国家”。

0                 HUN1                 ESP2                 GBR3                 ESP4                 FRA5             ID, USA6             GA, USA7    Hoboken, NJ, USA8             NJ, USA9                 AUS

将列分为三列就足够了:

location_df = df[''City, State, Country''].apply(lambda x: pd.Series(x.split('','')))

但是,这将创建左对齐数据:

     0       1       20    HUN     NaN     NaN1    ESP     NaN     NaN2    GBR     NaN     NaN3    ESP     NaN     NaN4    FRA     NaN     NaN5    ID      USA     NaN6    GA      USA     NaN7    Hoboken  NJ     USA8    NJ      USA     NaN9    AUS     NaN     NaN

如何将数据右对齐来创建新列?我是否需要遍历每一行,计算逗号的数量并分别处理内容?

答案1

小编典典

我将执行以下操作:

foo = lambda x: pd.Series([i for i in reversed(x.split('',''))])rev = df[''City, State, Country''].apply(foo)print rev      0    1        20   HUN  NaN      NaN1   ESP  NaN      NaN2   GBR  NaN      NaN3   ESP  NaN      NaN4   FRA  NaN      NaN5   USA   ID      NaN6   USA   GA      NaN7   USA   NJ  Hoboken8   USA   NJ      NaN9   AUS  NaN      NaN

我认为这可以为您提供所需的东西,但是如果您还想对东西进行修饰并获得“城市,州,国家”列的顺序,则可以添加以下内容:

rev.rename(columns={0:''Country'',1:''State'',2:''City''},inplace=True)rev = rev[[''City'',''State'',''Country'']]print rev     City State Country0      NaN   NaN     HUN1      NaN   NaN     ESP2      NaN   NaN     GBR3      NaN   NaN     ESP4      NaN   NaN     FRA5      NaN    ID     USA6      NaN    GA     USA7  Hoboken    NJ     USA8      NaN    NJ     USA9      NaN   NaN     AUS

Pandas 将列中的字符串值拆分为多行

Pandas 将列中的字符串值拆分为多行

如何解决Pandas 将列中的字符串值拆分为多行?

是的,我查过其他问题,但我仍然无法正确回答。

我有一个多列的 df,就像这样

id,hashtag
1234,[''hash1'',''hash2'',''hash3'']
1254,[hash1'']
1777,[''hash5'']

我希望输出为每个主题标签都有一行,然后将相同的标签分组以便获得它们的频率,例如:

hashtag,count
hash1,2
hash2,1
hash3,1
hash5,1

但是我得到的输出计数错误。这是我的代码:

hashtags_df = df[''hashtags''].value_counts().fillna(0).rename_axis(''hashtags'').reset_index(name=''counts'')
hashtags_df = df[''hashtags''].reset_index(name=''index'')
hashtags_df[''hashtags''] =  hashtags_df[''hashtags''].apply(lambda x: x.replace(''['','''').replace('']'','''')) #doing it because it seems like they''re not lists. I''m using twint to extract tweets by the way
hashtags_df[''hashtags''] = hashtags_df[''hashtags''].astype(''string'') #the dtype otherwise is an obj

hashtags_df.nunique().sum()


new_df = pd.DataFrame(hashtags_df.hashtags.str.split('','').tolist(),index=hashtags_df.counts).stack()
new_df = new_df.reset_index([0,''counts''])
new_df.columns =[''counts'',''hashtags'']
new_df = new_df[''hashtags''].value_counts().rename_axis(''hashtags'').reset_index(name="counts")

print(new_df)

我多次重新编写代码,现在它搞砸了。感觉解决方案很简单,但我找不到。我该怎么办?

解决方法

您可以将 explode 函数与 value_counts 一起使用。不需要任何其他东西。

df.hashtag \
  .explode() \
  .value_counts() \
  .reset_index() \
  .rename(columns={"index": "hashtag","hashtag": "counts"})

  hashtag  counts
0   hash1       2
1   hash5       1
2   hash2       1
3   hash3       1
,
import pandas

data = [
    [1234,[''hash1'',''hash2'',''hash3'']],[1254,[''hash1'']],[1777,[''hash5'']]
]

df = pd.DataFrame(data,columns = ["id","hashtag"])

output = df.explode("hashtag") \
          .groupby("hashtag") \
              .count().reset_index() \
                  .rename(columns={"id": "count"})

输出:

  hashtag  count
0   hash1      2
1   hash2      1
2   hash3      1
3   hash5      1

关于从Pandas Dataframe单元格中将嵌套数组值拆分为多行pandas dataframe 按列合并的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Dask Dataframe将列表的列拆分为多列、Pandas Dataframe将具有dict值的列拆分为列 输出、Pandas Dataframe:将列拆分为多列,右对齐不一致的单元格条目、Pandas 将列中的字符串值拆分为多行的相关知识,请在本站寻找。

本文标签: