I have an array and hash which I need to combine. Please let me know the simplest way to do this.
array1 = [:user_id, :project_id, :task_id]
entry_hash = {"User"=>1, "Project"=>[8], "Task"=>[87]}
When it is combined i want a hash like
output = {"user_id"=>1, "project_id"=>8, "task_id"=>87}
Thanks for the help!
It's a bit unclear to me what you want to achieve here. Looking at your example, the easiest solution would be to change the keys of entry_hash using .downcase and adding _id. For the value, you could check if it's an array and if so, use the first value.
output = {}
entry_hash.each do |key, value|
output[key.downcase + '_id'] = value.kind_of?(Array) ? value[0] : value
end
This assumes of course that the keys in the hash are the nouns for the column names in the array. The code above will not work if the names are more complex (e.g. CamelCaseName or snake_case_id). Rails comes with ActiveSupport that can help you there, but this is a totally different question: Converting camel case to underscore case in ruby
If array and hash don't share the same names there is no easy way to do this automatically. Hash doesn't guarantee the order of its elements, so iterating through both and mapping values like in the above snippet won't work reliably.
Related
Here is what I try to achieve:
In my Java code, at some place a Map (may be a HashMap) is created, that may not be sorted:
var map = Map.of("c","third entry","a","first entry","b","second entry");
var data = Map.of("map",map);
Later this map is passed to a stringtemplate loaded from a file with content similar to this:
delimiters "«", "»"
template(data) ::= <<
«data.map.keys:{key|• «data.map.(key)»}; separator="\n"»
>>
However, I want the generated list to be sorted by map key, but there seems to be no function like sort(list). Can I achieve what I want?
desired:
«sorted(data.map.keys):{key|• «data.map.(key)»}; separator="\n"»
I googled for this functionality for some time and I really wonder, whether nobody had wanted sorted lists before.
Of course, I could solve it by passing an extra (sorted) list of keys. But is there a straightforward approach?
best wishes :)
I have a model that has one attribute with a list of floats:
values = ArrayField(models.FloatField(default=0), default=list, size=64, verbose_name=_('Values'))
Currently, I'm getting my entries and order them according to the sum of all diffs with another list:
def diff(l1, l2):
return sum([abs(v1-v2) for v1, v2 in zip(l1, l2)])
list2 = [0.3, 0, 1, 0.5]
entries = Model.objects.all()
entries.sort(key=lambda t: diff(t.values, list2))
This works fast if my numer of entries is very slow small. But I'm afraid with a large number of entries, the comparison and sorting of all the entries will get slow since they have to be loaded from the database. Is there a way to make this more efficient?
best way is to write it yourself, right now you are iterating over a list over 4 times!
although this approach looks pretty but it's not good.
one thing that you can do is:
have a variable called last_diff and set it to 0
iterate through all entries.
iterate though each entry.values
from i = 0 to the end of list, calculate abs(entry.values[i]-list2[i])
sum over these values in a variable called new_diff
if new_diff > last_diff break from inner loop and push the entry into its right place (it's called Insertion Sort, check it out!)
in this way, in average scenario, time complexity is much lower than what you are doing now!
and maybe you must be creative too. I'm gonna share some ideas, check them for yourself to make sure that they are fine.
assuming that:
values list elements are always positive floats.
list2 is always the same for all entries.
then you may be able to say, the bigger the sum over the elements in values, the bigger the diff value is gonna be, no matter what are the elements in list2.
then you might be able to just forget about whole diff function. (test this!)
The only way to makes this really go faster, is to move as much work as possible to the database, i.e. the calculations and the sorting. It wasn't easy, but with the help of this answer I managed to actually write a query for that in almost pure Django:
class Unnest(models.Func):
function = 'UNNEST'
class Abs(models.Func):
function = 'ABS'
class SubquerySum(models.Subquery):
template = '(SELECT sum(%(field)s) FROM (%(subquery)s) _sum)'
x = [0.3, 0, 1, 0.5]
pairdiffs = Model.objects.filter(pk=models.OuterRef('pk')).annotate(
pairdiff=Abs(Unnest('values')-Unnest(models.Value(x, ArrayField(models.FloatField())))),
).values('pairdiff')
entries = Model.objects.all().annotate(
diff=SubquerySum(pairdiffs, field='pairdiff')
).order_by('diff')
The unnest function turns each element of the values into a row. In this case it happens twice, but the two resulting columns are instantly subtracted and made positive. Still, there are as many rows per pk as there are values. These need to be summed, but that's not as easy as it sounds. The column can't be simply be aggregated. This was by far the most tricky part—even after fiddling with it for so long, I still don't quite understand why Postgres needs this indirection. Of the few options there are to make it work, I believe a subquery is the single one expressible in Django (and only as of 1.11).
Note that the above behaves exactly the same as with zip, i.e. the when one array is longer than the other, the remainder is ignored.
Further improvements
While it will be a lot faster already when you don't have to retrieve all rows anymore and loop over them in Python, it doesn't change yet that it results in a full table scan. All rows will have to be processed, every single time. You can do better, though. Have a look into the cube extension. Use it to calculate the L1 distance—at least, that seems what you're calculating—directly with the <#> operator. That will require the use of RawSQL or a custom Expression. Then add a GiST index on the SQL expression cube("values"), or directly on the field if you're able to change the type from float[] to cube. In case of the latter, you might have to implement your own CubeField too—I haven't found any package yet that provides it. In any case, with all that in place, top-N queries on the lowest distance will be fully indexed hence blazing fast.
I wanted to get the unique values in a Data frame. I used drop.duplicates() but after that, i got the unique values but the indexing are not in natural order. Indexing was something like, 0,1,5,9,15, etc...I wanted a natural indexing like 0,1,2,3,4 etc after doing drop.duplicated(). How to do that?
Just reassign the index after drop duplcated, ie:
df.index = range(0,len(df))
df= df.reset_index()
should do the trick! For more information on what this does, and its arguments you can read the documentation below.
http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.reset_index.html
I have some constraints of the form Sizes[i1] + Sizes[i2] + Sizes[i3]<=1, which I add by
model.add(Sizes[i1] + Sizes[i2] + Sizes[i3]<=1)
for some specific indices i1,i2,i3. Later I want to add for all other index combinations the constraints
model.add(Sizes[k1] + Sizes[k2] + Sizes[k3]>1)
Is there some nice way to do this, e.g. to check if the constraint already exists in the model?
Maybe I can store the handle which is returned by the IloModel::add function (e.g. as an ILOExtracableArray or even IloConstraintArray?) but even then I con't know how to check if the contraint already exists.
Thank you
I don't think that there is really an easy way to get this back from a cplex model. I have previously had to do something similar in several projects, so I give my two suggestions below.
(1) If you know you always have the same number of things in each constraint, then you can create a structure to hold that information, like:
class tuple{
public int index1;
public int index2;
public int index3;
}
and then you can just create one for each constraint you add, and keep them in a list or array or similar.
(2) If you know about the possible values of the indices, then maybe you can create a hash-code or similar from the indices. If done right, this can also solve the issue of symmetry due to permuting the indices - (Sizes[a] + Sizes[b] + Sizes[c]) is the same as (Sizes[b] + Sizes[a] + Sizes[c]).
Then as above, you can keep the hash codes in a list or array for the constraints that you added.
I need to be able to insert numbers like 098532 into my table. This is the exact same question as this but I actually need to store it with the leading zeros as I will be using the data for 3rd party API calls.
The given answer was to format the output which doesn't really solve my problem.
Is the best solution to change the datatype of the column to a CHAR field?
I think your best bet is to store it as a string in a charfield and then cast it when you need something else.
i.e.
num = "051"
int(num)
if you need it as an int. Could you give a little more information about what the api expects and why you need the leading zeroes?