使用 tolist() 函数填充固定数量 (x) 的新列,有时包含较少的项目 (< x)
Filling a fixed number (x) of new columns with tolist() function which sometimes contains less items (< x)
我正在使用 tolist() 将 1 列 ('modelGreeks') 中的 8 项列表拆分为同一数据框中的 8 个新列:
pd.DataFrame(df['modelGreeks'].tolist(), index=df.index)
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = pd.DataFrame(df['modelGreeks'].tolist(), index=df.index)
这是我通常在 'modelGreeks' 列中获得的列表:
(0.2953686167703842, -1.9317880628477724e-14, 1.4648640549124297e-15, 0.0, 6.240571011994176e-13, 1.1840837166645831e-15, -1.4648640549124297e-15, 10.444000244140625)
10 次中有 9 次完美无缺。但有时我通过 API 检索的数据不是 perfect/complete。它不是在 'modelGreeks' 列中包含 8 个项目的预期列表,而是在该字段中提供了一个 'None' 值,我在第二个代码行的代码执行中收到以下错误消息(逻辑上,因为它试图仅用 1 个可用值填充 8 列:
ValueError: Columns must be same length as key
我正在寻找一种解决方案,无论如何都会创建并填充 8 个新列,例如0 或 NaN 或 None.
希望有人能帮忙。预先感谢您的努力。
以下代码有效:
df1 = pd.DataFrame(columns=['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice','modelGreeks'])
df1['modelGreeks'] = [[None, None, None, None, None, None, None, None], None, None, None, None]
df1[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df1['modelGreeks'].apply(pd.Series)
它returns:
IV_model 59 Price_model 61 62 63 64 undPrice modelGreeks
0 NaN NaN NaN NaN NaN NaN NaN NaN [None, None, None, None, None, None, None, None]
1 NaN NaN NaN NaN NaN NaN NaN NaN None
2 NaN NaN NaN NaN NaN NaN NaN NaN None
3 NaN NaN NaN NaN NaN NaN NaN NaN None
4 NaN NaN NaN NaN NaN NaN NaN NaN None
这很好。唯一的问题是,在某些时刻,我通过 API 从 Interactive Brokers 收到的数据集只会在 modelGreeks 列的所有行中提供一个标量 None 值。如果我将其应用于测试用例,则会再次收到错误消息 ("ValueError: Columns must be same length as key"):
df1 = pd.DataFrame(columns=['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice','modelGreeks'])
df1['modelGreeks'] = [None, None, None, None, None]
df1[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df1['modelGreeks'].apply(pd.Series)
Traceback (most recent call last):
File "/Users/floris/PycharmProjects/ib_insync/test1.py", line 9, in <module>
df1[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df1['modelGreeks'].apply(pd.Series)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py", line 3367, in __setitem__
self._setitem_array(key, value)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py", line 3389, in _setitem_array
raise ValueError('Columns must be same length as key')
ValueError: Columns must be same length as key
在这种情况下,我还希望在 8 列中只看到 NaN 值。
由于您要转换要列出的值,我建议您先检查列表的长度。如果它小于 8,则可以在其后附加 0。像这样:
lst = df['modelGreeks'].tolist()
lst += [0]*(8 - len(lst))
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = pd.DataFrame(np.array(lst).reshape(1,8), index=df.index)
我已经使用 np.array.reshape 来确保没有形状不匹配错误。
如果我正确理解您的问题,这可能会有所帮助。我相信一定有更酷的方法来做到这一点,其他人可能会帮助你,但这也应该完成任务。
您提出的第一个错误,
ValueError: Columns must be same length as key
当您提供的值与列数不匹配时,将输出。
例如,
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
print (df2)
df2[['team1','team2', 'team3']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
print (df2)
在这种情况下,不需要 'team3'。简单回顾一下您可能已经知道的事情。
然后让我们将列表中的最后一个条目替换为 None:
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],None]}
Produced error:
TypeError: object of type 'NoneType' has no len()
要删除 None 条目,只需执行以下操作:
df3 = df2.replace(to_replace='None', value=np.nan).dropna()
这应该不是问题,因为他们没有提供任何有价值的信息。
所以作为最后一个例子,你会像这样:
import pandas as pd
import numpy as np
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],None]}
df2 = pd.DataFrame(d1)
df3 = df2.replace(to_replace='None', value=np.nan).dropna()
df2[['team1','team2']] = pd.DataFrame(df3.teams.values.tolist(), index= df3.index)
print (df2)
这会产生:
teams team1 team2
0 [SF, NYG] SF NYG
1 [SF, NYG] SF NYG
2 [SF, NYG] SF NYG
3 [SF, NYG] SF NYG
4 [SF, NYG] SF NYG
5 [SF, NYG] SF NYG
6 None NaN NaN
希望这对您有用,如果您需要帮助将其应用到您的示例中,请告诉我。
不要创建新的 DataFrame,而是将列表列转换为 Series:
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df['modelGreeks'].apply(pd.Series)
测试:
df = pd.DataFrame(columns=['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice','modelGreeks'])
df['modelGreeks'] = [[1,2,3,4,5,6,7,8], [1,2,None,4,5,6,7,8], [1,2,3,4,5,6,7], [None], None, [None,None,None,None,None]]
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df['modelGreeks'].apply(pd.Series)
输出:
IV_model 59 Price_model ... 64 undPrice modelGreeks
0 1.0 2.0 3.0 ... 7.0 8.0 [1, 2, 3, 4, 5, 6, 7, 8]
1 1.0 2.0 NaN ... 7.0 8.0 [1, 2, None, 4, 5, 6, 7, 8]
2 1.0 2.0 3.0 ... 7.0 NaN [1, 2, 3, 4, 5, 6, 7]
3 NaN NaN NaN ... NaN NaN [None]
4 NaN NaN NaN ... NaN NaN None
5 NaN NaN NaN ... NaN NaN [None, None, None, None, None]
我正在使用 tolist() 将 1 列 ('modelGreeks') 中的 8 项列表拆分为同一数据框中的 8 个新列:
pd.DataFrame(df['modelGreeks'].tolist(), index=df.index)
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = pd.DataFrame(df['modelGreeks'].tolist(), index=df.index)
这是我通常在 'modelGreeks' 列中获得的列表:
(0.2953686167703842, -1.9317880628477724e-14, 1.4648640549124297e-15, 0.0, 6.240571011994176e-13, 1.1840837166645831e-15, -1.4648640549124297e-15, 10.444000244140625)
10 次中有 9 次完美无缺。但有时我通过 API 检索的数据不是 perfect/complete。它不是在 'modelGreeks' 列中包含 8 个项目的预期列表,而是在该字段中提供了一个 'None' 值,我在第二个代码行的代码执行中收到以下错误消息(逻辑上,因为它试图仅用 1 个可用值填充 8 列:
ValueError: Columns must be same length as key
我正在寻找一种解决方案,无论如何都会创建并填充 8 个新列,例如0 或 NaN 或 None.
希望有人能帮忙。预先感谢您的努力。
以下代码有效:
df1 = pd.DataFrame(columns=['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice','modelGreeks'])
df1['modelGreeks'] = [[None, None, None, None, None, None, None, None], None, None, None, None]
df1[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df1['modelGreeks'].apply(pd.Series)
它returns:
IV_model 59 Price_model 61 62 63 64 undPrice modelGreeks
0 NaN NaN NaN NaN NaN NaN NaN NaN [None, None, None, None, None, None, None, None]
1 NaN NaN NaN NaN NaN NaN NaN NaN None
2 NaN NaN NaN NaN NaN NaN NaN NaN None
3 NaN NaN NaN NaN NaN NaN NaN NaN None
4 NaN NaN NaN NaN NaN NaN NaN NaN None
这很好。唯一的问题是,在某些时刻,我通过 API 从 Interactive Brokers 收到的数据集只会在 modelGreeks 列的所有行中提供一个标量 None 值。如果我将其应用于测试用例,则会再次收到错误消息 ("ValueError: Columns must be same length as key"):
df1 = pd.DataFrame(columns=['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice','modelGreeks'])
df1['modelGreeks'] = [None, None, None, None, None]
df1[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df1['modelGreeks'].apply(pd.Series)
Traceback (most recent call last):
File "/Users/floris/PycharmProjects/ib_insync/test1.py", line 9, in <module>
df1[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df1['modelGreeks'].apply(pd.Series)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py", line 3367, in __setitem__
self._setitem_array(key, value)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py", line 3389, in _setitem_array
raise ValueError('Columns must be same length as key')
ValueError: Columns must be same length as key
在这种情况下,我还希望在 8 列中只看到 NaN 值。
由于您要转换要列出的值,我建议您先检查列表的长度。如果它小于 8,则可以在其后附加 0。像这样:
lst = df['modelGreeks'].tolist()
lst += [0]*(8 - len(lst))
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = pd.DataFrame(np.array(lst).reshape(1,8), index=df.index)
我已经使用 np.array.reshape 来确保没有形状不匹配错误。 如果我正确理解您的问题,这可能会有所帮助。我相信一定有更酷的方法来做到这一点,其他人可能会帮助你,但这也应该完成任务。
您提出的第一个错误,
ValueError: Columns must be same length as key
当您提供的值与列数不匹配时,将输出。
例如,
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
print (df2)
df2[['team1','team2', 'team3']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
print (df2)
在这种情况下,不需要 'team3'。简单回顾一下您可能已经知道的事情。
然后让我们将列表中的最后一个条目替换为 None:
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],None]}
Produced error:
TypeError: object of type 'NoneType' has no len()
要删除 None 条目,只需执行以下操作:
df3 = df2.replace(to_replace='None', value=np.nan).dropna()
这应该不是问题,因为他们没有提供任何有价值的信息。
所以作为最后一个例子,你会像这样:
import pandas as pd
import numpy as np
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],None]}
df2 = pd.DataFrame(d1)
df3 = df2.replace(to_replace='None', value=np.nan).dropna()
df2[['team1','team2']] = pd.DataFrame(df3.teams.values.tolist(), index= df3.index)
print (df2)
这会产生:
teams team1 team2
0 [SF, NYG] SF NYG
1 [SF, NYG] SF NYG
2 [SF, NYG] SF NYG
3 [SF, NYG] SF NYG
4 [SF, NYG] SF NYG
5 [SF, NYG] SF NYG
6 None NaN NaN
希望这对您有用,如果您需要帮助将其应用到您的示例中,请告诉我。
不要创建新的 DataFrame,而是将列表列转换为 Series:
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df['modelGreeks'].apply(pd.Series)
测试:
df = pd.DataFrame(columns=['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice','modelGreeks'])
df['modelGreeks'] = [[1,2,3,4,5,6,7,8], [1,2,None,4,5,6,7,8], [1,2,3,4,5,6,7], [None], None, [None,None,None,None,None]]
df[['IV_model', 59, 'Price_model', 61, 62, 63, 64, 'undPrice']] = df['modelGreeks'].apply(pd.Series)
输出:
IV_model 59 Price_model ... 64 undPrice modelGreeks
0 1.0 2.0 3.0 ... 7.0 8.0 [1, 2, 3, 4, 5, 6, 7, 8]
1 1.0 2.0 NaN ... 7.0 8.0 [1, 2, None, 4, 5, 6, 7, 8]
2 1.0 2.0 3.0 ... 7.0 NaN [1, 2, 3, 4, 5, 6, 7]
3 NaN NaN NaN ... NaN NaN [None]
4 NaN NaN NaN ... NaN NaN None
5 NaN NaN NaN ... NaN NaN [None, None, None, None, None]