Python 在维护索引的同时,将字符串化列表列表转换为数据帧
我有以下来自API源的数据帧,我试图在不大量更改原始数据帧的情况下对数据进行争论(本质上不想做笛卡尔乘积)Python 在维护索引的同时,将字符串化列表列表转换为数据帧,python,pandas,Python,Pandas,我有以下来自API源的数据帧,我试图在不大量更改原始数据帧的情况下对数据进行争论(本质上不想做笛卡尔乘积) 键值度量告诉数组的顺序,我正在尝试以{Key:Value}的字典方式对数组进行排序,其中键是连接的键和度量字段,值是嵌套列表的-1索引 源数据是通过excel和MS Graph API提供的,我不认为它会改变,但可能会改变,所以我正在尝试提出一个动态解决方案 我的目标数据帧是: target_df = pd.DataFrame({'id' : [0,1,2],
键
值
度量
告诉数组的顺序,我正在尝试以{Key:Value}的字典方式对数组进行排序,其中键是连接的键
和度量
字段,值是嵌套列表的-1
索引
源数据是通过excel和MS Graph API提供的,我不认为它会改变,但可能会改变,所以我正在尝试提出一个动态解决方案
我的目标数据帧是:
target_df = pd.DataFrame({'id' : [0,1,2],
'foo_bar' : [4,5,6],
'foo1_bar1' : [np.nan, np.nan,''],
'foo2_bar2' : [55.21, np.nan, 57.75]})
我自己的尝试是使用
ast
库中的literal_eval来获取第一个列表,该列表始终是键度量和值列-将来可能会出现键度量,度量2
,Value
字段-因此我希望保持事物的动态性
始终会有一个键
和值
字段
自己的尝试:
使用此方法,我替换了列表字符并用拆分,
然后将结果转换为数据帧:
df['arr'].str.replace('\[|\]','').str.split(',',expand=True)
然而,在这之后,我还没有弄清楚方向,不知道我是否走错了方向?我仍然不能完全确定我是否理解了问题的各个方面,但以下是我到目前为止所了解的
导入ast
作为pd进口熊猫
数据=[“['Key'、'Metric'、'Value']、['foo'、'bar'、'4']、['foo2'、'bar2'、'55.21']”,
“[['Key'、'Metric'、'Value']、['foo'、'bar'、'5']],
“[['Key'、'Metric'、'Value']、['foo'、'bar'、'6']、['foo1'、'bar1'、''、'foo2'、'bar2'、'57.75']]”
嵌套的_列表=[ast.literal_eval(elem)[1:]表示数据中的元素]
row_dicts=[{''''.join([key,metric]):key的值,metric,curr_list中的值}用于嵌套_list中的curr_list]
df=pd.数据帧(数据=行)
打印(df)
输出:
foo\u bar foo2\u bar2 foo1\u bar1
0455.21南
15楠楠
2 6 57.75
nested\u list
和row\u dicts
是列表理解,因为它使调试更容易,但您当然可以将它们转换为生成器表达式。IIUC,您可以在每一行上循环并使用literal\u eval
,创建数据帧,设置索引
前两列和转置
。然后concat
加上重命名列,并创建列id:
from ast import literal_eval
df_target = pd.concat([pd.DataFrame.from_records(literal_eval(x)).drop(0).set_index([0,1]).T
for x in df.arr.to_numpy()],
ignore_index=True,
keys=df.id) #to keep the ids
# rename the columns as wanted
df_target.columns = ['{}_{}'.format(*col) for col in df_target.columns]
# add the ids as a column
df_target = df_target.reset_index().rename(columns={'index':'id'})
print (df_target)
id foo_bar foo1_bar1 foo2_bar2
0 0 4 NaN 55.21
1 1 5 NaN NaN
2 2 6 57.75
尝试:
df2=df[“arr”].map(eval).apply(lambda x:pd.Series({f{el[0]}}{el[1]}):el[2]表示x[1:]}中的el)
df2[“id”]=df[“id”]
输出:
foo\u bar foo2\u bar2 foo1\u bar1 id
0455.21NAN0
1 5南南1
2 6 57.75 2
与实际子列表相比,键、值和度量字符串“无序”是否有任何原因?(我希望这足够清楚)@AMC-抱歉,拼写错误花了一段时间来阐述这个问题,经过了几次迭代。嗯,我还不确定我是否完全理解了这个问题。索引与此有什么关系?@AMC索引是原始数据帧,我基本上想在将数据摄入数据仓库之前,将这些列表分解为原始数据帧上的新列-简言之,我想保持原始形状。好的,接下来有几个不同的问题。如果你把这些列表作为数据帧,你知道从那里去哪里吗?启动cluster to test=)Ben这真的很好-我试图让它对我的目标数据集起作用,它有更多级别的嵌套列表,但结果总是出错-它把我推向了正确的方向,非常感谢您的帮助,并为没有正确地传达我的问题表示歉意。@DataNearior很高兴您找到了解决pb的方法:)@DataNearior我的目标数据集有更多级别的嵌套列表……这看起来很有希望,现在将进行测试。这也很好,但我的实际数据不是来自列表而是来自API@Datanovice不幸的是,你的帖子和你的评论却恰恰相反。您以什么格式获取数据?从接受的答案来看,您似乎只是想将现有列添加到新数据中?说到公认的答案,它使用了eval()
,这是非常不安全的。我所说的列表是指变量data
,它来自一个API调用,格式为列arr
中的第一个数据帧,谢谢@我猜“API调用”是一种调用API并将结果转换为数据帧的方法?或者您正在创建数据帧?感谢这一点-非常好地使用了f字符串,我将其转换为一个函数,以添加更多的逻辑,但它很好。谢谢你,伙计。
print(target_df)
id foo_bar foo1_bar1 foo2_bar2
0 0 4 NaN 55.21
1 1 5 NaN NaN
2 2 6 57.75
from ast import literal_eval
literal_eval(df['arr'][0])[0]
#['Key', 'Value', 'Metric']
df['arr'].str.replace('\[|\]','').str.split(',',expand=True)
from ast import literal_eval
df_target = pd.concat([pd.DataFrame.from_records(literal_eval(x)).drop(0).set_index([0,1]).T
for x in df.arr.to_numpy()],
ignore_index=True,
keys=df.id) #to keep the ids
# rename the columns as wanted
df_target.columns = ['{}_{}'.format(*col) for col in df_target.columns]
# add the ids as a column
df_target = df_target.reset_index().rename(columns={'index':'id'})
print (df_target)
id foo_bar foo1_bar1 foo2_bar2
0 0 4 NaN 55.21
1 1 5 NaN NaN
2 2 6 57.75