将元组列表转换为 Pandas 系列

问题描述 投票:0回答:7

我有一个元组列表,我想将其转换为系列。

return array2

[(0, 0.07142857142857142),
  (0, 0.07142857142857142),
  (1, 0.08333333333333333),
  (1, 0.3333333333333333),
  (1, 0.3333333333333333),
  (1, 0.08333333333333333),
  (3, 0.058823529411764705),
  (3, 0.058823529411764705)]

我尝试通过将列表转换为字典,然后转换为系列来做到这一点:

 a = pd.Series(dict(array2))

然而,最终的系列并没有达到我需要的效果。似乎会丢弃

key:value
对(可能是任意的?)

例如

return a

 0    0.071429
 1    0.083333
 3    0.058824

如何在不删除任何键值对的情况下获得一个系列?

python pandas dictionary tuples series
7个回答
26
投票

使用

zip
和顺序解包:

idx, values = zip(*L)

a = pd.Series(values, idx)

对于重复的索引,如在您的数据中,

dict
将无济于事,因为不允许重复的字典键:
dict
只会采用提供的每个键的最后一个值。


8
投票

在第一列使用

DataFrame
构造函数和
set_index
,然后为
Series
选择第二列:

a = pd.DataFrame(array2).set_index(0)[1]
print (a)
0
0    0.071429
0    0.071429
1    0.083333
1    0.333333
1    0.333333
1    0.083333
3    0.058824
3    0.058824
Name: 1, dtype: float64

或者创建 2 个列表并传递给

Series
构造函数:

idx = [x[0] for x in array2]
vals = [x[1] for x in array2]

a = pd.Series(vals, index=idx)
print (a)
0    0.071429
0    0.071429
1    0.083333
1    0.333333
1    0.333333
1    0.083333
3    0.058824
3    0.058824
dtype: float64

4
投票

问题在于,当您将元组列表转换为字典时,Python 会删除所有重复的键,只使用每个键的最后一个值。这是必要的,因为每个键只能在字典中出现一次。所以你需要使用一种保留所有记录的方法。这将做到这一点:

df = pd.DataFrame.from_records(array2, columns=['key', 'val'])
df = df.set_index('key')
a = df['val']

示例:

import pandas as pd
array2 = [
    (0, 0.07142857142857142),
    (0, 0.07142857142857142),
    (1, 0.08333333333333333),
    (1, 0.3333333333333333),
    (1, 0.3333333333333333),
    (1, 0.08333333333333333),
    (3, 0.058823529411764705),
    (3, 0.058823529411764705)
]

df = pd.DataFrame.from_records(array2, columns=['key', 'val'])
df = df.set_index('key')
a = df['val']
print(a)
# key
# 0    0.071429
# 0    0.071429
# 1    0.083333
# 1    0.333333
# 1    0.333333
# 1    0.083333
# 3    0.058824
# 3    0.058824
# Name: val, dtype: float64

4
投票

您可以使用

np.transpose
解压列,然后制作
pd.Series
:

import numpy as np
import pandas as pd

x, y = np.transpose(array2)
pd.Series(y, x)

1
投票

使用

MultiIndex

pd.MultiIndex.from_tuples(L).to_frame()[1].reset_index(level=1,drop=True)
Out[79]: 
0    0.071429
0    0.071429
1    0.083333
1    0.333333
1    0.333333
1    0.083333
3    0.058824
3    0.058824
Name: 1, dtype: float64

0
投票

假设您的元组列表是

tuples = [(0, 0.07142857142857142),
  (0, 0.07142857142857142),
  (1, 0.08333333333333333),
  (1, 0.3333333333333333),
  (1, 0.3333333333333333),
  (1, 0.08333333333333333),
  (3, 0.058823529411764705),
  (3, 0.058823529411764705)]

我会使用(显式优于隐式):

pd.Series([value for _, value in tuples], index=[index for index, _ in tuples])

但是,我也会重新考虑系列数据格式是否合适且有意义:索引实际上就像一个字典,即将唯一值映射到一个值。


0
投票

虽然这不是直接答案,但有时直接从元组列表中创建

pd.DataFrame
比创建
pd.Series
更容易,如果您稍后需要处理多个系列,则尤其如此。

跳过创建系列时,您可以将元组左值和右值作为 DataFrame 列,而不是索引和列。这避免了一些问题,例如元组数据中存在重复的索引键、None、NaN。

此外,创建 DataFrame 的代码更短且更易于阅读。

这里是如何直接进入DataFrame的示例:

# Prepare data as list of (value, timestamp) tuples
# Keep the order in mind
tvl_data = [(ps.total_equity, ps.calculated_at) for ps in state.stats.portfolio]
volume_data = [(t.get_volume(), t.executed_at) for t in state.portfolio.get_all_trades()]

# Convert to DataFrames without index
tvl = pd.DataFrame(tvl_data, columns=["tvl", "timestamp"])
volume = pd.DataFrame(volume_data, columns=["volume", "timestamp"])

# Merge DataFrames, index to a common index
df = pd.concat([tvl, volume]).set_index("timestamp")
display(df)

© www.soinside.com 2019 - 2024. All rights reserved.