我有两个数据框,如下所示
main_activity.xml
并且要求是根据df_input中的值填充df_ouput
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter here"
android:inputType="textPersonName"
android:textSize="26sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.371" />
<TextView
android:id="@+id/textView2"
android:layout_width="85dp"
android:layout_height="25dp"
android:layout_marginTop="88dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
因此,基本上,来自df_input的列值将是df_output中匹配并基于df_input.id == df_output.id的单元格值
我正在尝试以下
df_input df_output
id POLL_X POLL_Y POLL_Z .. id Pass_01 Pass_02 Pass_03 .....
110101 1 2 4 110101
110102 2 1 3 110102
-驱动程序功能---
df_input df_output
id POLL_X POLL_Y POLL_Z .... id Pass_01 Pass_02 Pass_03 .....
110101 1 2 3 110101 X Y Z
110102 2 1 3 110102 Y X Z
number_of_columnsiwthPass是常量,它给出名称为pass的列总数。
我也无法遍历每行,因为这将花费大量时间,必须在基于列或基于lambda的地方进行
两个数据帧中还有其他列,df_input.id == df_output.id也必须匹配
列的总数可以在40左右,一些测试值包括POLL_DNW,POLL_DO,POLL_DOES,POLL_SIG:2
所以我必须在'_'和列号之后加上01,02,03,04 ---- 10,11,-21,--- 39,40
答案 0 :(得分:1)
我假设一开始您具有正确的列名的 df_output (如填充后的样子)。
要执行任务:
import re
(稍后将使用)。
定义以下函数,根据源行生成输出行:
def genRow(row):
ind = []
vals = []
for k, v in row.iteritems():
mtch = re.match('POLL_(.+)', k)
if mtch:
ind.append('Pass_' + str(v).zfill(2))
vals.append(mtch.group(1))
else:
ind.append(k)
vals.append(v)
return pd.Series(vals, index=ind).rename(row.name)
请注意,此函数用“替换”任何 POLL _... 列 相应的 Pass _... 列,并保留其他列。
应用它:
df_output = df_input.apply(genRow, axis=1).reindex(columns=df_output.columns)
步骤:
df_input.apply(...)
-生成“初步”输出DataFrame。
请注意,目前列顺序为字母。reindex(...)
-使用列名为上述DataFrame重新索引
来自 df_output ,提供正确的列顺序。df_output =
-用上述结果覆盖 df_output 。如果您输入的DataFrame在 POLL _... 列中包含重复的值, 需要稍作修改。 这种情况导致输出行中这两个(或更多)元素具有 相同索引,因此如果无法构建整个DataFrame 包括这样的行。
补救措施是使用以下命令将这些元素“压缩”为一个元素: 原始索引,并将所有值转换为包含例如 逗号分隔的原始值列表。
要执行此操作,请将 genRow 函数中的最后一行更改为:
out = pd.Series(vals, index=ind).rename(row.name)
return out.groupby(lambda key: key).apply(lambda lst: (', '.join(sorted(lst))))
答案 1 :(得分:0)
从df_input创建两个数据帧并输出,将它们合并并向后旋转以得到最终的数据帧:
#create first dataframe
res1 = pd.wide_to_long(df,
stubnames='Pass',
i='id',
j='letters',
sep='_',
suffix='[A-Z]').reset_index()
)
res1
id letters Pass
0 110101 X 1
1 110102 X 2
2 110101 Y 2
3 110102 Y 1
4 110101 Z 4
5 110102 Z 3
#create second dataframe
res2 = (df1
.melt('id')
.drop('value', axis=1)
.assign(numbers=lambda x: x.variable.str.split('_').str.get(-1))
.astype( {'numbers': int})
)
res2
id variable numbers
0 110101 Pass_01 1
1 110102 Pass_01 1
2 110101 Pass_02 2
3 110102 Pass_02 2
4 110101 Pass_03 3
5 110102 Pass_03 3
#merge the two dataframes, and pivot to get ur final output
outcome = (res1
.merge(res2,
left_on=['id','Pass'],
right_on=['id','numbers'],
how='right')
.pivot(columns='variable',values='letters',index='id')
.bfill()
.reset_index()
.rename_axis(columns=None)
)
outcome
id Pass_01 Pass_02 Pass_03
0 110101 X Y Z
1 110102 Y X Z
答案 2 :(得分:0)
您可以使用Do I cast the result of malloc?,stack
以及一些unstack
和set_index
来处理逻辑中的列。
In [11]: import numpy as np
...: import math
...: c = []
...: angle=np.arange(0.1,10,1)
...: for d in angle:
...: r=(d*np.pi)/180
...: c.append(math.cos(r))
...:
In [12]: c
Out[12]:
[0.9999984769132877,
0.9998157121216442,
0.9993283937786562,
0.9985366703262117,
0.997440782930944,
0.9960410654107695,
0.9943379441332046,
0.9923319378854887,
0.9900236577165575,
0.9874138067509114]
注意:如果您不想在流程中包括其他列,请首先将它们设置为ID为索引的索引,例如df2 = (df1.set_index('id') #set index any columns not in the logic of pass
# remove the prefix Pass_
.rename(columns=lambda col: col.replace('Pass_', ''))
# stack the datafrae to make it a serie and sort the passes
.stack().sort_values()
# next two method exchange the old pass index to the new pass index
.reset_index(level=1, name='Pass')
.set_index('Pass', append=True)['level_1']
# from the serie to the dataframe shape
.unstack()
# rename the columns with the prefix pass_
.rename(columns=lambda col: f'Pass_{col:02}')
# rename axis to none
.rename_axis(None, axis=1)
# but back the id as a column
.reset_index())
print (df2)
id Pass_01 Pass_02 Pass_03
0 110101 X Y Z
1 110102 Y X Z